useSession() hook

useSession() is the core auth-state hook. It exposes the current session object plus the mutations that change active sign-ins, change organization or workspace scope, sign out, exchange tickets, and fetch session tokens.

Usage

The following example shows a basic usage of useSession().

export default function SessionSummary() {  const { session, loading } = useSession();  if (loading) {    return null;  }  return <div>{session.active_signin?.user.email_address}</div>;}

Return value

The hook returns the following fields and methods.

loading: boolean;
Whether the session request is still in flight.
error?: unknown | undefined;
The session-loading error, if one occurred.
refetch: () => Promise<void>;
Revalidate the current session state.
session?: Session | undefined;
The loaded session object. This is only available once loading has completed successfully.
active_signin?: SignIn | null | undefined;
The sign-in currently active in the session.
id?: string | undefined;
The active sign-in identifier.
active_organization_membership_id?: string | undefined;
The active organization membership attached to this sign-in.
active_workspace_membership_id?: string | undefined;
The active workspace membership attached to this sign-in.
expiresAt?: string | undefined;
When the current sign-in expires.
lastActiveAt?: string | undefined;
When the sign-in was last active.
user?: CurrentUser | undefined;
The current user attached to the active sign-in.
id?: string | undefined;
The current user identifier.
first_name?: string | undefined;
The user first name.
last_name?: string | undefined;
The user last name.
username?: string | undefined;
The username if one is set.
primary_email_address?: UserEmailAddress | undefined;
The primary email address for the current user.
email?: string | undefined;
The email address value.
verified?: boolean | undefined;
Whether the primary email address has been verified.
primary_phone_number?: UserPhoneNumber | undefined;
The primary phone number when one is available.
phone_number?: string | undefined;
The phone number value.
verified?: boolean | undefined;
Whether the primary phone number has been verified.
has_password?: boolean | undefined;
Whether the current user has a password set.
has_passkeys?: boolean | undefined;
Whether the current user has registered passkeys.
signins?: SignIn[] | undefined;
All sign-ins attached to the current session, including inactive ones in multi-session mode.
signin_attempts?: SigninAttempt[] | undefined;
Incomplete or resumable sign-in attempts attached to the current session.
id?: string | undefined;
The sign-in attempt identifier.
method?: SignInMethod | undefined;
The current sign-in method for the attempt.
current_step?: CurrentSessionStep | undefined;
The current step that still needs to be completed.
completed?: boolean | undefined;
Whether the sign-in attempt has completed.
second_method_authentication_required?: boolean | undefined;
Whether a second factor is still required.
available_2fa_methods?: string[] | undefined;
The second-factor methods available to this attempt.
requires_completion?: boolean | undefined;
Whether the attempt still needs profile completion.
missing_fields?: string[] | undefined;
The fields still missing from an incomplete profile.
profile_completion_data?: ProfileCompletionData | undefined;
The profile fields that can be prefilled during completion.
first_name?: string | undefined;
The suggested first name.
last_name?: string | undefined;
The suggested last name.
username?: string | undefined;
The suggested username.
email?: string | undefined;
The suggested email address.
phone_number?: string | undefined;
The suggested phone number.
signup_attempts?: SignupAttempt[] | undefined;
Incomplete or resumable sign-up attempts attached to the current session.
id?: string | undefined;
The sign-up attempt identifier.
current_step?: SignupAttemptStep | undefined;
The verification step the sign-up attempt is currently on.
remaining_steps?: SignupAttemptStep[] | undefined;
The verification steps that still remain.
completed?: boolean | undefined;
Whether the sign-up attempt has completed.
required_fields?: string[] | undefined;
The fields the sign-up flow requires.
missing_fields?: string[] | undefined;
The required fields still missing from the sign-up attempt.
switchSignIn?: (signInId: string) => Promise<void> | undefined;
Switch the active account inside a multi-sign-in session.
switchOrganization?: (organizationId?: string) => Promise<void> | undefined;
Change the active organization scope in the current session.
switchWorkspace?: (workspaceId: string) => Promise<void> | undefined;
Change the active workspace scope in the current session.
signOut?: (signInId?: string) => Promise<void> | undefined;
Sign out one sign-in when an ID is provided, or sign out the entire session when it is omitted.
getToken?: (template?: string) => Promise<string> | undefined;
Read a bearer token for the current session. Tokens are cached by template until expiry and cleared when session state changes.
exchangeTicket?: (ticket: string) => Promise<void> | undefined;
Exchange a ticket for session state during redirect or handshake flows.

How it works

The hook fetches the current session with SWR and keeps it warm with a periodic refresh instead of rebuilding session state separately inside each auth surface.
The return value is split into a loading branch and a loaded branch. While the session is still loading, the mutation methods are intentionally unavailable.
Session mutations clear the shared token cache and invalidate related organization, workspace, and notification state where needed.
Calling switchSignIn() also refreshes organization and workspace memberships, because the active account can change the available scopes completely.
Calling signOut(signInId) signs out one sign-in. Calling signOut() signs out the whole session and then follows the deployment-configured post-sign-out URL when one is set.
Calling getToken() without a live session throws instead of returning an empty token. Successful token reads are cached per template until the token expires.

When to use it

  • Use this when the app needs to know which sign-in is active.
  • This is also where account switching and token reads live on the client side.

Examples

Read active session state

export default function SessionSummary() {  const { session, loading } = useSession();  if (loading) {    return null;  }  return <div>{session.active_signin?.user.email_address}</div>;}

Switch accounts in a multi-session app

export default function AccountSwitcher() {  const { session, loading, switchSignIn } = useSession();  if (loading || !session.signins?.length) {    return null;  }  return session.signins.map((signin) => (    <button key={signin.id} onClick={() => switchSignIn(signin.id)}>      {signin.user.email_address}    </button>  ));}

Read a bearer token for an authenticated request

export default function PrivateRequestButton() {  const { getToken, loading } = useSession();  async function callPrivateApi() {    const token = await getToken();    await fetch('/api/private', {      headers: {        Authorization: `Bearer ${token}`,      },    });  }  if (loading) {    return null;  }  return <button onClick={callPrivateApi}>Call private API</button>;}

On this page