Configuration
Every option both clients accept, and how to override them per request.
A note on casing
The SDK mixes two conventions on purpose:
- Library options are camelCase —
throwErrors,trackUser,storageKeys. - Fields that travel to the platform are snake_case —
access_token,status_code,redirect_uri.
Nothing is renamed on the way in or out, so what you read in a response is what the platform sent.
ClientOptions
Accepted by createClient. createServerClient accepts the same minus
storage and storageKeys.
language() => LanguageOptionaldefault 'en-US'Returns the BCP 47 tag sent on every request.
timeoutnumberOptionalAbort requests after this many milliseconds.
debugbooleanOptionalLog request and response info to the console.
headersRecord<string, string> | (() => Record<string, string>)OptionalExtra headers merged into every request. Pass a function to resolve them per request.
throwErrorsbooleanOptionaldefault falseThrow NulvlessException instead of returning { data: null, error }.
storageNulvlessStorageOptionalAdapter for persisting session tokens. Defaults to localStorage in the
browser and to an in-memory store of the client's own elsewhere. Browser
client only — see Storage.
storageKeys{ token?: string; accounts?: string }OptionalOverride the storage keys. Default to nlv-<slug>-token and
nlv-<slug>-token-accounts. Browser only.
autoRefreshbooleanOptionaldefault trueRenew the access token on a timer, ahead of expiry, instead of waiting for a request to find it expired. Turn it off when the host controls renewal itself. Browser only — see SessionManager.
multiUserbooleanOptionaldefault falseKeep several signed-in accounts and enable auth.add / list / switch /
remove. Browser only.
trackUserbooleanOptionalSend nlv-user-tracking, so the platform collects device and browser data for
the session.
Lazy headers
headers accepts a function, resolved on each request. That is how you forward
a per-request value without rebuilding the client:
createServerClient(url, key, {
trackUser: true,
headers: () => forwardUserHeaders(cls.get('req')),
});Per-request options
Most methods take an options object as their last argument, which overrides the client-level configuration for that one call.
await nulvless.auth.signIn(params, {
timeout: 5000,
throwErrors: true,
headers: forwardUserHeaders(req),
});Request headers are merged over client headers case-insensitively: a header you pass replaces a client-level one or a default with the same name in any letter case, so no header is ever sent twice.
nonce is not a request option. It goes in the params of the sudo-protected
method — it is how a single call satisfies sudo mode without elevating the whole
session:
await nulvless.auth.sessions.revoke({ id, nonce });It is sent as the nlv-sudo-nonce header, never in the body.
Language
createClient(url, key, { language: () => 'pt-BR' });The tag decides which template language the platform renders for any message that call triggers — a verification email sent during sign-up, for example.