Skip to content
Zeitlos
Dashboard

Authentication

.md

API 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

TypeScript
import { createClient } from '@zeitlosapp/sdk';

const client = createClient(); // zero-config in a hosted app

It'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:

TypeScript
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

MethodReturns
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
TypeScript
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

CallExtra fieldEffect
sendVerificationEmailcallbackURLOverride where the user lands after verifying
forgetPasswordredirectToOverride the reset page for this call

Types

TypeScript
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:

TypeScript
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 });
  }
}
CodeWhen
INVALID_EMAIL_OR_PASSWORDsignIn credentials didn't match
USER_ALREADY_EXISTSsignUp with an already-registered email
EMAIL_NOT_VERIFIEDsignIn blocked because the email isn't verified
RESET_PASSWORD_NOT_CONFIGUREDforgetPassword with no reset page configured
INVALID_TOKENresetPassword 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.