Accounts & auth
Session-based auth for humans: login with optional TOTP, self-registration, password resets, invitations, and OIDC single sign-on.
Login
POST /api/v2/auth/login
{ "email_address": "ada@acme.com", "password": "…", "totp_code": "123456" }
# 201 → { session_token, expires_at, user }Put the token in Authorization: Bearer for every subsequent call. Error codes tell you what is going on: InvalidCredentials, TOTPRequired (user has 2FA, code missing), AccountLocked (too many attempts; the lockout window is configurable).
Registration
POST /api/v2/auth/register
{ "email_address": "ada@acme.com", "first_name": "Ada", "last_name": "Lovelace", "password": "…" }
# 201 → same shape as login: you are signed in immediatelyAvailable when the instance enables auth.allow_registration (the cloud does; self-hosted installations default to off and get RegistrationDisabled). Duplicate emails and short passwords are ValidationErrors.
Session & account
GET /api/v2/auth/me # who am I POST /api/v2/auth/logout POST /api/v2/auth/password # change password
Two-factor (TOTP)
POST /api/v2/auth/totp/enroll # returns the otpauth:// secret POST /api/v2/auth/totp/activate # confirm with a first code POST /api/v2/auth/totp/disable
Password resets & invitations
POST /api/v2/auth/password-reset # request a reset token POST /api/v2/auth/password-reset/complete # set the new password GET /api/v2/auth/invitations/{token} # inspect an invitation POST /api/v2/auth/invitations/accept
Reset and invitation tokens are surfaced to the operator/frontend rather than emailed by the platform itself. Your
auth.frontend_url decides where the links point. Tokens are stored hashed and expire (password_reset_expiry_hours, invitation_expiry_days).OIDC single sign-on
GET /api/v2/auth/oidc/start # redirect to the IdP GET /api/v2/auth/oidc/callback # register this as the redirect URI
Works with any OIDC provider: Okta, Entra ID, Google, Keycloak. Setup walkthrough: How-to: SSO.
Related configuration
| Key | Default | Meaning |
|---|---|---|
auth.session_timeout_days | 14 | Session lifetime |
auth.max_login_attempts | 5 | Before lockout |
auth.lockout_minutes | 15 | Lockout window |
auth.minimum_password_length | 8 | Applies to registration, resets, changes |
auth.allow_registration | false | Self-registration on/off |
auth.allow_organization_creation | true | May signed-in users create orgs |
