Bring your team’s work into focus.
A complete authentication and onboarding flow with visible labels, recoverable validation, progress, and useful setup choices.
- Invite collaborators when you are ready.
- Import data or begin with a clean workspace.
- Change every preference later.
“Our team was organized before the kickoff call.”— Amina, Northstar Labs
- 1Account
- 2Workspace
- 3Preferences
- 4Invite
Create your workspace
We’ll use these details to prepare the right starting point.
Explore login examples or visit the template gallery.
Returning members
A familiar way back in.
Email codes and passkeys, composed with Lumen. These visual examples do not send codes or sign you in.
Welcome back
Use a saved passkey or receive a code by email.
No password to remember.
Check your inbox
If this address can sign in, a code will arrive shortly.
Paste the complete code from your email.
Entered the wrong address? Return to email sign-in.
Try another way
You can still use email when your passkey is unavailable.
Your existing account and workspace stay the same.
Connect the UI to Auth
For applications with access to the private Auth workspace, connect @santi020k/auth-client alongside your Lumen adapter. Lumen supplies the fields, buttons, and feedback; Auth supplies email-code and passkey operations. These snippets are optional integration references and do not run in this preview.
import { createSantiAuthHelpers } from '@santi020k/auth-client'
// Use your application's configured auth origin and route.
export const auth = createSantiAuthHelpers({
baseURL: 'https://app.example.com',
basePath: '/api/auth'
})import { auth } from './auth'
export async function requestCode(email: string) {
const result = await auth.requestEmailOtp(email)
return result.ok
? { ok: true, message: 'If this address can sign in, a code will arrive shortly.' }
: { ok: false, message: result.error.message }
}
export async function verifyCode(email: string, code: string) {
return auth.signInWithEmailOtp(email, code)
}import { auth } from './auth'
export async function signInWithPasskey() {
const result = await auth.signInWithPasskey()
// Show only the safe message; keep the email fallback available.
return result.ok
? { ok: true, message: 'Signed in.' }
: { ok: false, message: result.error.message }
}Handle loading and duplicate submissions in your UI. Advance only after an ok result, and render error.message on failure. Keep diagnostics and credentials out of the UI. Your application owns the auth server, email delivery, code expiry and resend limits, route guards, session checks, and the destination after sign-in. Passkeys require a secure origin and a registered credential. See the Auth client contract and server integration checklist.