Authentication (login, logout, session)
Login with email and password
Returns a JWT token in both the response body and an httpOnly access_token cookie.
Login with email and password › Request Body
emailpasswordtotp_codeTOTP authenticator code, when completing a TOTP-2FA login.
email_codeThe emailed OTP, when completing an email-2FA login.
request_email_codeWhen true, ask the server to email an OTP instead of verifying a code on this request.
turnstile_tokenCloudflare Turnstile token, when the CAPTCHA widget is enabled.
remember_meWhen true, issue a longer-lived "remember me" session (7 days, cookie Max-Age and JWT exp) instead of the default TTL. Only takes effect after 2FA succeeds; ignored on 2FA-challenge responses.
Login with email and password › Responses
Login successful
tokenJWT token
Request a password-reset code (agent)
Always returns a generic success regardless of whether the email is registered (enumeration-safe). When it is, a 6-digit reset code is emailed (10-minute TTL, 60s resend cooldown).
Request a password-reset code (agent) › Request Body
emailturnstile_tokenRequired when the Turnstile widget is enabled.
Request a password-reset code (agent) › Responses
Generic acknowledgement (no enumeration).
Set a new password with a reset code (agent)
Verifies the emailed 6-digit code and sets a new password (min 8 chars). Unknown email and wrong/expired code return the same generic 422. On success all existing sessions are revoked.
Set a new password with a reset code (agent) › Request Body
emailcodeThe 6-digit reset code.
new_passwordturnstile_tokenSet a new password with a reset code (agent) › Responses
Password updated; sign in again.
Begin Google SSO login
Redirects the browser to Google's authorization endpoint and sets the short-lived sso_flow state cookie (login-CSRF guard). When Google SSO is not configured, rate limited, or the provider errors, it instead 302-redirects to the frontend login page with an sso_error query code (e.g. not_configured, rate_limited).
Begin Google SSO login › Responses
Redirect to the IdP authorization URL, or to the frontend login page with sso_error when the flow cannot start.
Google SSO callback (OIDC redirect URI)
Completes the Google OIDC code exchange. The state query param must equal the sso_flow cookie. On success, 302-redirects to the frontend (/login?sso=ok) with the access_token session cookie set; on failure, 302-redirects to the frontend login page with an sso_error query code.
query Parameters
codeAuthorization code from the IdP.
stateCSRF state issued at /start; must equal the sso_flow cookie.
errorPresent when the user cancels at the IdP (e.g. access_denied).
Google SSO callback (OIDC redirect URI) › Responses
Redirect to the frontend (session cookie set on success only)
Discover company SSO availability for an email
Checks whether an enabled company SSO provider accepts the email's domain. Reveals availability only — never a tenant name or issuer (enumeration-safe). When available, returns a relative start_url carrying a single-use ticket.
Discover company SSO availability for an email › Request Body
emailturnstile_tokenCloudflare Turnstile token, when the CAPTCHA widget is enabled.
Discover company SSO availability for an email › Responses
Discovery result
sso_availableTrue when an enabled company SSO provider accepts the email's domain.
start_urlRelative URL that begins the company SSO flow (carries a single-use ticket). Null when no provider matches.
Begin company SSO login (ticket from /discover)
query Parameters
ticketSingle-use ticket minted by POST /api/auth/sso/discover.
Begin company SSO login (ticket from /discover) › Responses
Redirect to the company IdP authorization URL, or to the frontend login page with sso_error for an invalid/expired ticket.
Company SSO callback (OIDC redirect URI)
Completes the company OIDC code exchange. Same contract as the Google callback — state must equal the sso_flow cookie; success sets the session cookie and 302-redirects to the frontend, failure redirects with an sso_error query code.
query Parameters
codeAuthorization code from the IdP.
stateCSRF state issued at /start; must equal the sso_flow cookie.
errorPresent when the user cancels at the IdP (e.g. access_denied).
Company SSO callback (OIDC redirect URI) › Responses
Redirect to the frontend (session cookie set on success only)
Begin a passkey (WebAuthn) login ceremony
Begin a passkey (WebAuthn) login ceremony › Request Body
turnstile_tokenCloudflare Turnstile token, when the CAPTCHA widget is enabled.
Begin a passkey (WebAuthn) login ceremony › Responses
WebAuthn request options for navigator.credentials.get
challenge_idServer-side ceremony id; echo it back on the matching verify call.
optionsWebAuthn options to pass to the browser (navigator.credentials.create for registration, navigator.credentials.get for login).
Complete a passkey login
Verifies the WebAuthn assertion (user verification required) and, on success, issues a session exactly like /api/auth/login. All failure modes return the same generic 401.
Complete a passkey login › Request Body
challenge_idThe id returned by /api/auth/passkeys/login/options.
credentialThe PublicKeyCredential assertion from navigator.credentials.get.
Complete a passkey login › Responses
Login successful
tokenJWT token
Begin passkey registration for the current agent
Requires an authenticated session. Forces a discoverable (resident) credential with user verification; credentials already registered by this agent are excluded so a device cannot double-enroll.
Begin passkey registration for the current agent › Responses
WebAuthn creation options for navigator.credentials.create
challenge_idServer-side ceremony id; echo it back on the matching verify call.
optionsWebAuthn options to pass to the browser (navigator.credentials.create for registration, navigator.credentials.get for login).
Complete passkey registration
Complete passkey registration › Request Body
challenge_idThe id returned by /api/auth/passkeys/register/options.
credentialThe RegisterPublicKeyCredential from navigator.credentials.create.
device_labelOptional friendly device name shown in the passkey list.
Complete passkey registration › Responses
Passkey stored
idcreated_atdevice_labelFriendly device name shown in the passkey list.
last_used_atList company SSO providers
Requires the admin-only sso.manage permission. Client secrets are never returned — only the has_client_secret flag.
List company SSO providers › Responses
Configured SSO providers
idprovider_nameissuer_urlclient_idhas_client_secretTrue when a client secret is stored. The secret itself is never returned.
allowed_email_domainsenabledrequire_email_verifiedcreated_atupdated_atCreate a company SSO provider
Requires the admin-only sso.manage permission. The issuer URL is validated and at least one allowed email domain is required.
Create a company SSO provider › Request Body
provider_nameissuer_urlOIDC issuer base URL (must serve an OIDC discovery document).
client_idclient_secretStored encrypted at rest; never returned by the API.
allowed_email_domainsenabledrequire_email_verifiedCreate a company SSO provider › Responses
Provider created
idprovider_nameissuer_urlclient_idhas_client_secretTrue when a client secret is stored. The secret itself is never returned.
allowed_email_domainsenabledrequire_email_verifiedcreated_atupdated_atUpdate a company SSO provider
Requires the admin-only sso.manage permission. All fields optional; an omitted or empty client_secret keeps the stored one.
path Parameters
idUpdate a company SSO provider › Request Body
provider_nameissuer_urlclient_idclient_secretallowed_email_domainsenabledrequire_email_verifiedUpdate a company SSO provider › Responses
Updated provider
idprovider_nameissuer_urlclient_idhas_client_secretTrue when a client secret is stored. The secret itself is never returned.
allowed_email_domainsenabledrequire_email_verifiedcreated_atupdated_atRegister a new tenant organization
Self-service tenant registration. Creates a new organization and spawns provisioning in the background. Returns a JWT so the user can start using the app immediately while provisioning completes.
Register a new tenant organization › Request Body
org_nameName of the new organization
admin_emailEmail for the initial admin user
admin_passwordPassword for the initial admin user (min 6 characters)
Register a new tenant organization › Responses
Organization created and provisioning started
tokenJWT token for immediate use
org_idmessage