Interactive
Browser-facing endpoints backing the hosted auth UI (/ui): password sign-in, local registration, and sign-out. Same-origin JSON; not part of the OAuth2/OIDC wire protocol.
Endpoints
- Password sign-in (hosted auth UI)POST
/v1/auth/sign-inVerifies a user's email + password with layered brute-force defense and, on success, establishes an interactive login session (Set-Cookie) and returns redirectTo: the /authorize continuation the browser follows so a single server path issues the authorization code (and later clients reuse the session). The body ALSO carries the preserved OAuth authorization parameters, which the server RE-VALIDATES against the client registry — the SPA-supplied redirect_uri/scope are never trusted. Failures return a uniform problem+json (401 invalid credentials, 429 throttled/locked) so the endpoint cannot be used to enumerate accounts. - Local account registration (hosted auth UI)POST
/v1/auth/registerCreates a local user with an argon2id-hashed password when self-service registration is enabled (config auth.registration.enabled; gate this in production). The username is set to the lowercased email so distinct emails never collide on the username uniqueness constraint. Like sign-in, the body carries the preserved OAuth parameters and the response may establish a session and return the /authorize continuation. When the deployment asks for a captcha (auth.captcha.provider), captcha must carry a solution of a challenge from GET /v1/auth/captcha. - The captcha the hosted UI must solve (hosted auth UI)GET
/v1/auth/captchaSays which captcha this deployment asks for (auth.captcha.provider). For the built-in proof-of-work provider it hands out a fresh challenge the ALTCHA widget solves: parameters and signature are its wire format, so the widget can fetch this URL directly. For a hosted provider it names the site key the provider's widget is shown with. The solution goes back in the captcha field of the request the captcha guards, which refuses a missing, wrong, expired or already used one with 400 captcha_failed, and answers 503 unavailable when a hosted provider cannot be asked. Issuing a challenge stores nothing. - Ask for a password-reset link (hosted auth UI)POST
/v1/auth/password-resetEmails a single-use link to set a new password to the account holding email in this organization, when there is one and the organization has an email relay. The answer is 202 whether or not there is: the account is looked up, and the link queued, after the response, so neither the status, the body nor the time taken tells whether the address has an account here. The link works for auth.password_reset.validity, and an account is sent at most auth.password_reset.max_requests within that time; the requests count toward the per-address sign-in throttle. With a captcha configured, the request must carry a captcha solution; a refusal, 400 captcha_failed, is the same whatever the address. - Set a new password from a reset link (hosted auth UI)POST
/v1/auth/password-reset/confirmSets the password of the account a reset link was sent to, and spends the link and every other one its account holds. A link that was never issued, has expired, was already used or belongs to another organization is refused alike, 400 invalid_reset_link, and a password the schema refuses leaves the link unspent. Setting it ends the account's sessions and the grants issued under them, and clears a lockout from failed sign-ins, as an administrator's password reset does. Requests count toward the per-address sign-in throttle. - Choose a password from an invitation link (hosted auth UI)POST
/v1/auth/invitation/acceptSets the password of the account an administrator invited, verifies the address the invitation was sent to, and spends that link and every other invitation the account holds. A link that was never issued, has expired, was already used, belongs to another organization, or was sent to an account that has a password by now or holds another address is refused alike, 400 invalid_invitation_link, and a password the schema refuses leaves the link unspent. The account has no session yet: the invitee signs in with the new password. Requests count toward the per-address sign-in throttle. - Ask for a link that verifies an email address (hosted auth UI)POST
/v1/auth/verify-email/resendEmails a single-use link that verifies the address to the account holding email in this organization, when there is one, its address is not yet verified, and the organization has an email relay. The answer is 202 whether or not there is: the account is looked up, and the link queued, after the response, so neither the status, the body nor the time taken tells whether the address has an account here. The link works for auth.email_verification.validity, and an account is sent at most auth.email_verification.max_requests within that time; the requests count toward the per-address sign-in throttle. With a captcha configured, the request must carry a captcha solution; a refusal, 400 captcha_failed, is the same whatever the address. - Verify an email address from a link (hosted auth UI)POST
/v1/auth/verify-email/confirmMarks the address a verification link was sent to as verified, and spends the link and every other verification link its account holds. A link that was never issued, has expired, was already used, belongs to another organization, or was sent to an address the account no longer holds is refused alike, 400 invalid_verification_link. Requests count toward the per-address sign-in throttle. - Begin a sign-in through an identity providerGET
/v1/auth/federation/{slug}/startSends the browser to the organization's identity provider slug (OpenID Connect Core 1.0 §3.1.2.1) with a state, a nonce and a PKCE challenge, and sets a short-lived cookie binding the flow to this browser. The query carries the preserved authorization parameters, as the sign-in body does; intent says which button was pressed. - The identity provider's redirect backGET
/v1/auth/federation/{slug}/callbackTakes the flow's state back once, redeems code at the provider and verifies its ID token (OpenID Connect Core 1.0 §3.1.3.7). The verified subject signs in as the account linked to it; failing that, as an existing account holding its address when the provider is trusted for email and says the address is verified; failing that, as a new account when the client allows sign-up through the provider and the organization accepts sign-up. - Sign out of the interactive session (hosted auth UI)POST
/v1/auth/sign-outRevokes the current interactive login session (server-side) and clears the session cookie. Returns 200 whether or not a session existed, so it never signals that. - Answer an RP-initiated logout confirmation (RP-Initiated Logout 1.0 §2)POST
/v1/auth/logout/confirmCompletes or abandons a logout parked by /end_session. The handle is single-use: the parked request is consumed whether the user confirms or declines, so a handle left in browser history cannot sign anyone out later. - Describe the pending authorization request (OIDC Core §3.1.2.4)POST
/v1/auth/consentReturns what the client is asking for, resolved server-side from the validated authorization request. The SPA renders this and nothing from its own URL: a consent screen showing an attacker-supplied application name or scope list is a phishing page. - Record the user's consent decision (OIDC Core §3.1.2.4)POST
/v1/auth/consent/decisionRecords the grant on approval and returns the /authorize continuation, or returns the client's redirect_uri carrying access_denied on refusal (RFC 6749 §4.1.2.1: "the resource owner denied the request"). - Look up a device authorization by its user code (RFC 8628 §3.3)POST
/v1/auth/device/verifyResolves a user-entered user_code so the hosted UI can show WHAT is being authorized (the client and the requested scope) before the user decides. It makes no decision itself. - Approve or deny a device authorization (RFC 8628 §3.3)POST
/v1/auth/device/decisionRecords the signed-in user's decision for a pending device authorization. Approval binds the user's identity and authentication facts to the device code, which the device's next /token poll then redeems; denial makes that poll return access_denied. - Begin (or re-display) TOTP enrollmentGET
/v1/auth/mfa/totp/enrollReturns the show-once enrollment payload for the current partial-auth session: the otpauth:// URI (for a QR code) and the Base32 secret (for manual entry). A first call mints a pending secret; repeat calls idempotently re-display the SAME secret until it is activated. The secret is returned only in the response body over HTTPS (never in a URL) and the response is marked no-store. GET, not POST, precisely so the secret is never placed in a query string. - Confirm and activate TOTP enrollmentPOST
/v1/auth/mfa/totp/activateConfirms the pending factor by verifying the first code, activates it, and returns the single-use recovery codes exactly ONCE. It does NOT elevate the session — the flow parks at the recovery-codes step until they are acknowledged (recovery-ack), so the codes can never be skipped. - Acknowledge saved recovery codes and complete enrollmentPOST
/v1/auth/mfa/totp/recovery-ackThe user's one-time "I saved these" acknowledgement after activation. It elevates the pending session to a full login session and returns the /authorize continuation. Until this is called the flow stays at the recovery-codes step. - Verify a TOTP code during sign-in (step-up)POST
/v1/auth/mfa/totp/verifyVerifies a TOTP code against the user's active factor for the current partial-auth session. The request carries ONLY the code; the OAuth continuation is read from the server-side pending-auth handle, never the client. On success the session is elevated and redirectTo resumes the flow. Failures are uniform (401 invalid, 429 locked/throttled). - Redeem a single-use recovery code during sign-inPOST
/v1/auth/mfa/recovery-code/verifyRedeems one single-use recovery code for the current partial-auth session — the escape hatch when the authenticator is unavailable. On success the code is consumed, the session is elevated, and redirectTo resumes the flow. Failures are uniform with the TOTP challenge. - Regenerate recovery codesPOST
/v1/auth/mfa/recovery-codesRe-authenticates with a current TOTP code, then voids the existing recovery-code set and issues a fresh one, returned exactly once. Requires an elevated session. - MFA status for the current sessionGET
/v1/auth/mfaReports the user's MFA enrollment status for settings screens: whether a factor is enrolled, the enrolled method kinds, and how many recovery codes remain. Requires an elevated session. - Disable (remove) the TOTP factorDEL
/v1/auth/mfa/totpRemoves the user's TOTP factor after re-authenticating with a current code, and voids the associated recovery codes. Requires an elevated session. Under a mandatory-MFA policy the user is forced to re-enroll on the next sign-in.