Skip to main content
The getAccessToken function retrieves an access token for the currently authenticated user from client components. It automatically handles token refresh if the token has expired.

Import

import { getAccessToken } from '@auth0/nextjs-auth0';
This function can only be called from client components or browser environments.

Signature

function getAccessToken(options?: AccessTokenOptions): Promise<string>;
function getAccessToken(
  options: AccessTokenOptions & { includeFullResponse: true }
): Promise<AccessTokenResponse>;

Parameters

options
AccessTokenOptions
Configuration options for fetching the access token.
options.audience
string
The unique identifier of the target API. Required when calling multiple APIs with different audiences.
When using audience or scope, ensure Multi-Resource Refresh Tokens (MRRT) is configured in your Auth0 Application settings.
options.scope
string
Additional scopes to request beyond those granted during login.Example: 'read:profile write:profile'
options.includeFullResponse
boolean
default:"false"
When true, returns the full response object instead of just the access token string.

Return Value

Default Return (string)

By default, returns the access token as a string:
const token: string = await getAccessToken();

Full Response Return

When includeFullResponse: true, returns an object with:
token
string
The access token string.
scope
string
The scopes granted for this token.
expires_at
number
Unix timestamp (in seconds) when the token expires.
expires_in
number
Number of seconds until the token expires.
token_type
string
Token type (typically "Bearer").

Basic Usage

app/components/api-caller.tsx
"use client";

import { getAccessToken } from '@auth0/nextjs-auth0';

export default function ApiCaller() {
  async function fetchData() {
    try {
      const token = await getAccessToken();
      
      const response = await fetch('https://api.example.com/data', {
        headers: {
          Authorization: `Bearer ${token}`
        }
      });
      
      const data = await response.json();
      console.log(data);
    } catch (error) {
      console.error('Failed to fetch data:', error);
    }
  }

  return <button onClick={fetchData}>Fetch Data</button>;
}

Full Response Usage

"use client";

import { getAccessToken } from '@auth0/nextjs-auth0';

export default function TokenInfo() {
  async function showTokenInfo() {
    try {
      const tokenSet = await getAccessToken({
        includeFullResponse: true
      });
      
      console.log('Token:', tokenSet.token);
      console.log('Expires in:', tokenSet.expires_in, 'seconds');
      console.log('Expires at:', new Date(tokenSet.expires_at! * 1000));
      console.log('Scopes:', tokenSet.scope);
    } catch (error) {
      console.error('Failed to get token:', error);
    }
  }

  return <button onClick={showTokenInfo}>Show Token Info</button>;
}

Multi-Resource Refresh Tokens (MRRT)

When your application calls multiple APIs with different audiences, you must specify the audience parameter:
"use client";

import { getAccessToken } from '@auth0/nextjs-auth0';

export default function MultiApiCaller() {
  async function fetchFromMultipleApis() {
    try {
      // Get token for profile API
      const profileToken = await getAccessToken({
        audience: 'https://profile-api.example.com'
      });
      
      // Get token for orders API
      const ordersToken = await getAccessToken({
        audience: 'https://orders-api.example.com'
      });
      
      // Call both APIs with their respective tokens
      const [profileData, ordersData] = await Promise.all([
        fetch('https://profile-api.example.com/me', {
          headers: { Authorization: `Bearer ${profileToken}` }
        }).then(r => r.json()),
        fetch('https://orders-api.example.com/orders', {
          headers: { Authorization: `Bearer ${ordersToken}` }
        }).then(r => r.json())
      ]);
      
      console.log({ profileData, ordersData });
    } catch (error) {
      console.error('Failed to fetch:', error);
    }
  }

  return <button onClick={fetchFromMultipleApis}>Fetch All Data</button>;
}
When using MRRT, ensure the audiences and scopes are configured in your Auth0 Application’s Refresh Token Policies. See the Auth0 MRRT documentation for setup instructions.

Custom Scopes

"use client";

import { getAccessToken } from '@auth0/nextjs-auth0';

export default function AdminActions() {
  async function performAdminAction() {
    try {
      const token = await getAccessToken({
        audience: 'https://api.example.com',
        scope: 'read:users write:users delete:users'
      });
      
      const response = await fetch('https://api.example.com/admin/users', {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${token}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ action: 'create_user' })
      });
      
      const result = await response.json();
      console.log(result);
    } catch (error) {
      console.error('Admin action failed:', error);
    }
  }

  return <button onClick={performAdminAction}>Create User</button>;
}

Error Handling

"use client";

import { getAccessToken } from '@auth0/nextjs-auth0';
import { AccessTokenError } from '@auth0/nextjs-auth0/errors';

export default function SecureDataFetcher() {
  async function fetchSecureData() {
    try {
      const token = await getAccessToken();
      
      const response = await fetch('https://api.example.com/secure', {
        headers: { Authorization: `Bearer ${token}` }
      });
      
      if (!response.ok) {
        throw new Error('API request failed');
      }
      
      const data = await response.json();
      console.log(data);
    } catch (error) {
      if (error instanceof AccessTokenError) {
        console.error('Token error:', error.code, error.message);
        // Redirect to login
        window.location.href = '/auth/login';
      } else {
        console.error('Fetch error:', error);
      }
    }
  }

  return <button onClick={fetchSecureData}>Fetch Secure Data</button>;
}

Token Caching

For client-side token caching to avoid redundant requests:
"use client";

import { getAccessToken } from '@auth0/nextjs-auth0';
import { useState, useEffect } from 'react';

export default function CachedTokenFetcher() {
  const [tokenCache, setTokenCache] = useState<{
    token: string;
    expiresAt: number;
  } | null>(null);

  async function getToken() {
    // Check if cached token is still valid
    if (tokenCache && tokenCache.expiresAt > Date.now() / 1000 + 60) {
      return tokenCache.token;
    }
    
    // Fetch new token
    const tokenSet = await getAccessToken({ includeFullResponse: true });
    
    // Cache the token
    setTokenCache({
      token: tokenSet.token,
      expiresAt: tokenSet.expires_at!
    });
    
    return tokenSet.token;
  }

  async function fetchData() {
    const token = await getToken();
    const response = await fetch('https://api.example.com/data', {
      headers: { Authorization: `Bearer ${token}` }
    });
    const data = await response.json();
    console.log(data);
  }

  return <button onClick={fetchData}>Fetch Data</button>;
}

API Route

The client-side getAccessToken function makes a request to /auth/access-token (configurable via NEXT_PUBLIC_ACCESS_TOKEN_ROUTE). The SDK automatically provides this route handler, but you can customize it:
app/api/auth/access-token/route.ts
import { auth0 } from '@/lib/auth0';
import { NextRequest, NextResponse } from 'next/server';

export async function GET(req: NextRequest) {
  const session = await auth0.getSession();
  
  if (!session) {
    return NextResponse.json(
      { error: { code: 'unauthorized', message: 'Not authenticated' } },
      { status: 401 }
    );
  }
  
  const searchParams = req.nextUrl.searchParams;
  const audience = searchParams.get('audience') || undefined;
  const scope = searchParams.get('scope') || undefined;
  
  try {
    const { token, expiresAt, scope: grantedScope } = await auth0.getAccessToken({
      audience,
      scope
    });
    
    return NextResponse.json({
      token,
      expires_at: expiresAt,
      scope: grantedScope,
      token_type: 'Bearer'
    });
  } catch (error) {
    return NextResponse.json(
      { error: { code: 'access_token_error', message: error.message } },
      { status: 500 }
    );
  }
}

TypeScript

import { getAccessToken } from '@auth0/nextjs-auth0';
import type { AccessTokenOptions } from '@auth0/nextjs-auth0';

const options: AccessTokenOptions = {
  audience: 'https://api.example.com',
  scope: 'read:data'
};

// String return type
const token: string = await getAccessToken(options);

// Full response return type
const tokenSet = await getAccessToken({
  ...options,
  includeFullResponse: true
});

console.log(tokenSet.token); // string
console.log(tokenSet.expires_in); // number | undefined

Custom Environment Variables

.env.local
# Default: /auth/access-token
NEXT_PUBLIC_ACCESS_TOKEN_ROUTE=/api/auth/access-token

See Also

Build docs developers (and LLMs) love