Interactive
Docs version v1 (main)Nauthera is pre-1.0, in a design-partner program
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 or the password policy refuses leaves the link unspent. Setting it ends the account's sessions and the grants issued under them, clears a lockout from failed sign-ins, as an administrator's password reset does, and clears an administrator's requirement to set a new password. An account under that requirement is refused 400 password_reused for a new password that is its current one, and the link stays unspent. 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. - Route an email address to the member organization that owns its domainPOST
/v1/auth/broker/routeThe broker's email-first step (docs/design/IDENTITY-BROKER.md §4). When the address's domain is verified by a member organization whose active membership admits client_id, the answer's redirectTo is the broker's start of a sign-in at that member, carrying the preserved authorization parameters and the address as login_hint. Otherwise the answer has no redirectTo, the same whether the domain is unknown, unverified, or verified by an organization that is not a member. - Begin a sign-in at a member organization of this brokerGET
/v1/auth/broker/{member}/startSends the browser to the member organization member's own authorization endpoint with the membership's reserved client, a state, a nonce and a PKCE challenge, and sets a short-lived cookie binding the hop to this browser (docs/design/IDENTITY-BROKER.md §3). The query carries the preserved authorization parameters, as the sign-in body does. - The member organization's redirect back to this brokerGET
/v1/auth/broker/{member}/callbackTakes the hop's state back once, checks it was issued to this browser for this member, and that iss is the member's issuer (RFC 9207 §2.4). Redeems code at the member in process with the PKCE verifier and verifies the member's ID token (OpenID Connect Core 1.0 §3.1.3.7). - 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). - Send the code that enrolls the email second factorPOST
/v1/auth/mfa/email/enrollMails a single-use code to the account's verified address, which email/activate answers to enroll it as a second factor, and names the address only masked. Asking again sends a new code that replaces the last. An address that is not verified is refused (email_unverified), as is an account that already holds the factor (409). - Confirm and activate the email second factorPOST
/v1/auth/mfa/email/activateVerifies the code email/enroll mailed, activates the factor, and returns the single-use recovery codes exactly once, as totp/activate does. The flow parks at the recovery-codes step until they are acknowledged. - Send a sign-in code to the email second factorPOST
/v1/auth/mfa/email/sendMails a single-use code to the address the account's email factor was enrolled against, which email/verify answers, and names the address only masked. Asking again sends a new code that replaces the last. An account holding no email factor is answered as a pending sign-in that cannot continue (401). - Verify an emailed code during sign-in (step-up)POST
/v1/auth/mfa/email/verifyVerifies the code email/send mailed for the current partial-auth session. On success the session is elevated, recording acr aal1, and redirectTo resumes the flow. Failures are uniform with the TOTP challenge (401 invalid, 429 locked). - Begin a passkey registration ceremonyPOST
/v1/auth/mfa/passkey/registration/optionsIssues the options the browser creates a passkey from for the current partial-auth session: a fresh single-use challenge, the account's opaque handle, the algorithms offered, and the credentials the account already holds. Answered with registration/verify. - Verify a passkey registration and enroll the credentialPOST
/v1/auth/mfa/passkey/registration/verifyVerifies the browser's registration against the challenge issued to this partial-auth session and stores the credential, active at once. For the account's first second factor the single-use recovery codes are returned exactly ONCE and the flow parks at the recovery-codes step (recovery-ack); for a further factor the session is elevated and redirectTo resumes the flow. A registration that does not verify is answered uniformly (401). - Begin a passkey authentication ceremonyPOST
/v1/auth/mfa/passkey/authentication/optionsIssues the options the browser signs an assertion with for the current partial-auth session: a fresh single-use challenge and the passkeys the account holds. Answered with authentication/verify. An account holding no passkey is answered as a pending sign-in that cannot continue (401). - Verify a passkey assertion during sign-in (step-up)POST
/v1/auth/mfa/passkey/authentication/verifyVerifies the browser's assertion against the challenge issued to this partial-auth session and the credential's stored key. On success the session is elevated and redirectTo resumes the flow. Failures are uniform (401). - Decline the offer to add a passkey and complete the sign-inPOST
/v1/auth/mfa/passkey/offer/declineFor a sign-in completed up to the offer of a passkey (passkeyOffered): records the decline, so the offer is not made again for mfa.passkey.offer_interval, and elevates the pending session on the factors already proven: the password, and the one-time code when the offer followed one. A pending sign-in that owes a second factor it has not answered cannot finish this way (401). - Begin a passwordless passkey sign-inPOST
/v1/auth/passkey/optionsIssues the options the browser signs an assertion with for a sign-in that names no account (W3C WebAuthn Level 3 §6.3.3): a fresh single-use challenge and no credential list, so the browser offers every discoverable credential it holds for this relying party. Answered with /v1/auth/passkey/verify. A deployment serving no passkeys answers 503. - Sign in with a passkey and no passwordPOST
/v1/auth/passkey/verifyLike a password sign-in, it must name a client_id registered in the organization or the device verification page as continue_path, or it is refused with 404 not_found before the assertion is checked. - 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.