Authentication
View as markdown.mdAPI reference
Every authentication method, type and error code in the Zeitlos SDK.
The auth surface of @zeitlosapp/sdk, reached as client.auth. It is browser-safe: the
session is an httpOnly cookie, so these calls work from client components as well as server
code.
createClient
import { createClient } from '@zeitlosapp/sdk';
const client = createClient(); // zero-config in a hosted appIt'll know automatically how to talk to the Zeitlos authentication endpoints.
Only in local development if you changed the ports.auth variable in your zeitlos.dev.json, you'll need to tell the client how to reach the auth endpoints. See local development for more details.
Note
The Zeitlos authentication endpoints are living under /__auth. This means any URL under
that path won't be routed to your app, so you can't use URLs beginning with /__auth.
createClientForUser
Binds a server request's session to the client, so every auth call carries it:
import { cookies } from 'next/headers';
import { createClientForUser } from '@zeitlosapp/sdk';
const client = createClientForUser({ cookies: await cookies() });
const user = await client.auth.getUser();Accepts one of { cookies } (a Next cookie store or a raw cookie string), { request } (a
Request, NextRequest or Node IncomingMessage), or { headers } (a Headers or a Node
headers record).
Methods
| Method | Returns |
|---|---|
signUp({ email, password, name }) | AuthUser |
signIn({ email, password }) | AuthUser |
signOut() | void |
getUser() | AuthUser | null |
getUser({ profile: true }) | AuthUserWithProfile | null |
updateProfile(patch) | the updated profile values |
sendVerificationEmail({ email }) | void |
forgetPassword({ email }) | void |
resetPassword({ token, newPassword }) | void |
await client.auth.signUp({ email, password, name });
await client.auth.signIn({ email, password });
await client.auth.signOut();
const user = await client.auth.getUser();
const me = await client.auth.getUser({ profile: true });
await client.auth.updateProfile({ bio: 'Hello' });
await client.auth.sendVerificationEmail({ email });
await client.auth.forgetPassword({ email });
await client.auth.resetPassword({ token, newPassword });getUser is the one call that does not throw when there is no session — it returns null.
Optional inputs
| Call | Extra field | Effect |
|---|---|---|
sendVerificationEmail | callbackURL | Override where the user lands after verifying |
forgetPassword | redirectTo | Override the reset page for this call |
Types
interface AuthUser {
id: string;
email: string;
emailVerified: boolean;
name?: string;
image?: string | null;
createdAt?: string;
}
interface AuthUserWithProfile<P> extends AuthUser {
profile: MaskedProfile<P>;
}
type ProfileValues = Record<string, string | string[] | null>;MaskedProfile<P> makes every field of P optional and nullable — absent when not visible
to the caller, null when visible but unset. See
Profile fields.
Errors
Auth calls throw ZeitlosError with a machine-readable .code:
import { ZeitlosError } from '@zeitlosapp/sdk';
try {
await client.auth.signIn({ email, password });
} catch (err) {
if (err instanceof ZeitlosError && err.code === 'EMAIL_NOT_VERIFIED') {
await client.auth.sendVerificationEmail({ email });
}
}| Code | When |
|---|---|
INVALID_EMAIL_OR_PASSWORD | signIn credentials didn't match |
USER_ALREADY_EXISTS | signUp with an already-registered email |
EMAIL_NOT_VERIFIED | signIn blocked because the email isn't verified |
RESET_PASSWORD_NOT_CONFIGURED | forgetPassword with no reset page configured |
INVALID_TOKEN | resetPassword with an expired or already-used token |
The list isn't exhaustive — treat unknown codes generically.
Not in the SDK
This is the end-user surface: your own session and your own profile. Administrative operations — listing users, editing someone else's profile, defining profile fields — happen in the dashboard or through the MCP server.