Skip to Content

Authentication

Login, token refresh, logout, OAuth and email verification. Login is form-encoded and returns a JWT for user-context flows.

Refresh access token

GET/api/v1/auth/refresh
User session

Validate the refresh token (read from the `refresh_token` httpOnly cookie) and issue a new access token. Subject to IP-based rate limiting.

Error responses
  • 401 Refresh token is missing or invalid
  • 429 Too many refresh attempts from this IP
Request

Log in with email and password

POST/api/v1/auth/login
No authentication

Authenticate a user with username (email) and password. On success, sets httpOnly access and refresh cookies and returns the user profile and tokens. Subject to IP-based rate limiting and account lockout after repeated failures. In SaaS mode, the account's email must be verified.

Request bodyapplication/x-www-form-urlencodedrequired

usernamestringrequired
passwordstringrequired
org_slugstring | null
Error responses
  • 401 Incorrect email or password
  • 403 Email not verified (SaaS mode)
  • 422 Validation ErrorHTTPValidationError
  • 423 Account is locked due to too many failed attempts
  • 429 Too many login attempts from this IP
Request
Response
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

Log in via third-party provider

POST/api/v1/auth/oauth
User session

Sign in or sign up using a third-party OAuth provider (currently Google). On success, sets httpOnly access and refresh cookies and returns the user profile and tokens.

Query parameters

org_idinteger | null
invite_codestring | null

Request bodyapplication/jsonrequired

emailstringrequired
providerstringrequired
access_tokenstringrequired
Error responses
  • 400 Unknown org_id or unsupported provider
  • 401 Third-party authentication failed
  • 403 Organization is invite-only and no valid invite was provided
  • 422 Validation ErrorHTTPValidationError
  • 503 Invitation could not be verified; retry
Request
Response
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

Request a passwordless login link by email

POST/api/v1/auth/magic-link/request
User session

Emails a one-time, short-lived login link to the address if an account exists. Always returns 200 with the same body regardless of whether the account exists, so it cannot be used to enumerate users.

Request bodyapplication/jsonrequired

emailstringrequired
org_slugstring | null
Error responses
  • 422 Validation ErrorHTTPValidationError
  • 429 Too many requests
Request
Response
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

Complete a passwordless login

POST/api/v1/auth/magic-link/verify
User session

Exchange a one-time login-link token for a session. If the account has two-factor enabled, returns an `mfa_token` instead and no cookies are set until the code is verified at /auth/login/mfa.

Request bodyapplication/jsonrequired

tokenstringrequired
Error responses
  • 410 Link invalid or already used
  • 422 Validation ErrorHTTPValidationError
Request
Response
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

Log out the current user

DELETE/api/v1/auth/logout
User session

Log out the current user by clearing the access and refresh cookies. Because JWTs are stored in httpOnly cookies, the frontend cannot clear them directly — the backend must respond with cookie-clearing headers.

Error responses
  • 401 No authenticated session was found
Request

Verify user email

POST/api/v1/auth/verify-email
User session

Verify a user's email address using the token delivered via verification email. Rate limited to 5 attempts per 5 minutes per user_uuid.

Request bodyapplication/jsonrequired

tokenstringrequired
user_uuidstringrequired
org_uuidstringrequired
emailstring | null
Error responses
  • 422 Validation ErrorHTTPValidationError
  • 429 Too many verification attempts for this user
Request
Response
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

Resend verification email

POST/api/v1/auth/resend-verification
User session

Resend the email-verification email for a user. The underlying service enforces its own rate limiting and will return a generic response whether or not an account exists.

Request bodyapplication/jsonrequired

emailstringrequired
org_idinteger | null
Error responses
  • 422 Validation ErrorHTTPValidationError
  • 429 Too many verification email requests — rate limited
Request
Response
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

Get the caller's two-factor status

GET/api/v1/auth/mfa/status
User session
Request

Begin two-factor enrollment

POST/api/v1/auth/mfa/setup
User session

Generate a TOTP secret and return the `otpauth://` provisioning URI. The factor is NOT active until confirmed with a valid code.

Request bodyapplication/jsonrequired

passwordstring | null
Error responses
  • 401 Incorrect password
  • 409 Two-factor is already enabled
  • 422 Validation ErrorHTTPValidationError
Request
Response
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

Confirm and activate two-factor enrollment

POST/api/v1/auth/mfa/confirm
User session

Verify a code from the authenticator app, activate the factor, and return single-use backup codes. The codes are shown exactly once.

Request bodyapplication/jsonrequired

codestringrequired
Error responses
  • 400 No enrollment in progress, or invalid code
  • 422 Validation ErrorHTTPValidationError
  • 429 Too many attempts
Request
Response
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

Disable two-factor authentication

POST/api/v1/auth/mfa/disable
User session

Requires both the current password (when the account has one) and a valid code, so a hijacked session alone cannot strip the factor.

Request bodyapplication/jsonrequired

passwordstring | null
codestringrequired
Error responses
  • 400 Invalid code
  • 401 Incorrect password
  • 422 Validation ErrorHTTPValidationError
Request
Response
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

Regenerate backup codes

POST/api/v1/auth/mfa/backup-codes/regenerate
User session

Invalidates all existing codes and returns a fresh batch, shown exactly once.

Request bodyapplication/jsonrequired

codestringrequired
Error responses
  • 422 Validation ErrorHTTPValidationError
Request
Response
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

Complete login with a second factor

POST/api/v1/auth/login/mfa
User session

Exchange the short-lived `mfa_token` returned by `/auth/login` plus a TOTP or backup code for a real session.

Request bodyapplication/jsonrequired

mfa_tokenstringrequired
codestringrequired
is_backup_codeboolean
Error responses
  • 401 Expired or invalid pending token, or invalid code
  • 422 Validation ErrorHTTPValidationError
  • 429 Too many attempts
Request
Response
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

Get the caller's two-factor compliance state for an org

GET/api/v1/auth/mfa/org-policy/{org_id}
User session

Drives the in-app banner and the blocking interstitial. `blocking` is true only once the grace deadline has passed without enrollment.

Path parameters

org_idintegerrequired
Error responses
  • 422 Validation ErrorHTTPValidationError
Request
Response
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

Set the org-wide two-factor requirement

PUT/api/v1/auth/mfa/org-policy/{org_id}
User session

Admin/maintainer only. Enabling the policy requires the calling admin to already have two-factor enabled themselves.

Path parameters

org_idintegerrequired

Request bodyapplication/jsonrequired

require_2faboolean | null
require_2fa_grace_daysinteger | null
exempt_external_authboolean | null
allowed_auth_methodsstring[] | null
allow_central_session_sharingboolean | null
Error responses
  • 403 Not an org admin, or admin has not enrolled themselves
  • 422 Validation ErrorHTTPValidationError
Request
Response
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

Get the org's saved security policy

GET/api/v1/auth/mfa/org-policy/{org_id}/settings
User session

Admin/maintainer only. Returns the policy exactly as stored, read straight from the database. The settings UI reads it from here rather than from the cached organization payload, so a save is never followed by the previous values reappearing.

Path parameters

org_idintegerrequired
Error responses
  • 403 Not an org admin
  • 422 Validation ErrorHTTPValidationError
Request
Response
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

List members and whether they have two-factor enabled

GET/api/v1/auth/mfa/org-compliance/{org_id}
User session

Admin/maintainer only. Intended to be checked BEFORE switching the policy on — enabling it blind is how an org locks out its own staff.

Path parameters

org_idintegerrequired
Error responses
  • 422 Validation ErrorHTTPValidationError
Request
Response
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

Reset (clear) a member's two-factor factor

POST/api/v1/auth/mfa/org-reset/{org_id}/{user_id}
User session

Admin/maintainer recovery tool. Removes a member's TOTP factor and all their backup codes so they can re-enroll — the supported path for a member who lost their device with no backup codes left. Does not enroll anything on their behalf; if the org requires 2FA the member re-enters their grace window and must set it up again.

Path parameters

org_idintegerrequired
user_idintegerrequired
Error responses
  • 400 Cannot reset your own factor here — use /mfa/disable
  • 403 Not an org admin, or target is a platform superadmin
  • 404 Target user is not a member of this org
  • 422 Validation ErrorHTTPValidationError
Request
Response
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}