Skip to main content
Use Auth0 SDKs to fetch access tokens for social and enterprise identity providers from Auth0’s Token Vault. Using these access tokens, AI agents integrated with the application can call third-party APIs to perform tasks on the user’s behalf. By the end of this quickstart, you should have an AI application integrated with Auth0 that can:
  1. Retrieve access tokens for a Google social connection.
  2. Integrate with an AI agent to call Google APIs.

Pick your tech stack

  • https://mintlify-assets.b-cdn.net/auth0/vercel.svg Next.js
  • https://mintlify-assets.b-cdn.net/auth0/vercel.svg React SPA

Prerequisites

Before getting started, make sure you have completed the following steps:
1

Create an Auth0 Account

To continue with this quickstart, you need to have an Auth0 account.
2

Create an Auth0 Application

Go to your Auth0 Dashboard to create a new Auth0 Application.
  • Navigate to Applications > Applications in the left sidebar.
  • Click the Create Application button in the top right.
  • In the pop-up select Regular Web Applications and click Create.
  • Once the Application is created, switch to the Settings tab.
  • Scroll down to the Application URIs section.
  • Set Allowed Callback URLs as: http://localhost:3000/auth/callback
  • Set Allowed Logout URLs as: http://localhost:3000
  • Click Save in the bottom right to save your changes.
To learn more about Auth0 applications, read Applications.
3

Enable Token Exchange Grant

Enable the Token Exchange Grant for your Auth0 Application. Go to Applications > [Your Application] > Settings > Advanced > Grant Types and enable the Token Exchange grant type.
4

Configure Google Social Integration

Set up a Google developer account that allows for third-party API calls by following the Google Social Integration instructions.
5

OpenAI Platform

Prerequisites

Before getting started, make sure you have completed the following steps:

Prepare Next.js app

Recommended: To use a starter template, clone the Auth0 AI samples repository:
git clone https://github.com/auth0-samples/auth0-ai-samples.git
cd auth0-ai-samples/authenticate-users/vercel-ai-next-js

Install dependencies

In the root directory of your project, install the following dependencies:
  • @auth0/ai-vercel: Auth0 AI SDK for Vercel AI built for GenAI applications powered by the Vercel AI SDK.
  • ai: Core Vercel AI SDK module that interacts with various AI model providers.
  • @ai-sdk/openai: OpenAI provider for the Vercel AI SDK.
  • @ai-sdk/react: React UI components for the Vercel AI SDK.
  • zod: TypeScript-first schema validation library.
  • googleapis: Node.js client for Google APIs that supports authentication and authorization with OAuth 2.0.
npm install @auth0/ai-vercel@3 ai@4 @ai-sdk/openai@1 @ai-sdk/react@1 zod@3 googleapis@148

Update the environment file

Copy the .env.example file to .env.local and update the variables with your Auth0 credentials. You can find your Auth0 domain, client ID, and client secret in the application you created in the Auth0 Dashboard.

Get access tokens for other APIs

Use the Auth0 AI SDK to get access tokens for third-party APIs.

Set up Token Vault for Google Social Connection

Setup Auth0 AI SDK for Google Social Connection. This will allow you to get access tokens for Google Social Connection using Token Vault.
  • connection: pass in the name of the connection you want the user to sign up for/log into.
  • refreshToken: pass in the function to get the refresh token from the current session.
  • scopes: pass in the scopes for the service you want to get access to.
Create a file at src/lib/auth0-ai.ts and instantiate a new Auth0 AI SDK client:
src/lib/auth0-ai.ts
import { Auth0AI, getAccessTokenForConnection } from "@auth0/ai-vercel";
import { getRefreshToken } from "./auth0";

// Get the access token for a connection via Auth0
export const getAccessToken = async () => getAccessTokenForConnection();

const auth0AI = new Auth0AI();

// Connection for Google services
export const withGoogleConnection = auth0AI.withTokenForConnection({
  connection: "google-oauth2",
  scopes: ["https://www.googleapis.com/auth/calendar.events"],
  refreshToken: getRefreshToken,
});
Update the /src/lib/auth0.ts file with the following code:
src/lib/auth0.ts
//...
//... existing code
// Get the refresh token from Auth0 session
export const getRefreshToken = async () => {
  const session = await auth0.getSession();
  return session?.tokenSet?.refreshToken;
};

Use access token to call APIs from a tool

Once the user is authenticated, you can fetch an access token from the Token Vault using the Auth0 AI SDK. In this example, we fetch an access token for a Google social connection. Once you’ve obtained the access token for a social connection, you can use it with an AI agent to fetch data during a tool call and provide contextual data in its response.In our example, we create a file at src/lib/tools/google-calendar.ts. In the file, we define a tool, getCalendarEventsTool, that uses the access token with the Google Calendar API to query for calendar events in a specified date:
src/lib/tools/google-calendar.ts
import { tool } from 'ai';
import { endOfDay, formatISO, startOfDay } from 'date-fns';
import { GaxiosError } from 'gaxios';
import { google } from 'googleapis';
import { z } from 'zod';
import { FederatedConnectionError } from '@auth0/ai/interrupts';

import { getAccessToken, withGoogleConnection } from '../auth0-ai';

export const getCalendarEventsTool = withGoogleConnection(
  tool({
    description: `Get calendar events for a given date from the user's Google Calendar`,
    parameters: z.object({
      date: z.coerce.date(),
    }),
    execute: async ({ date }) => {
      // Get the access token from Auth0 AI
      const accessToken = await getAccessToken();

      // Google SDK
      try {
        const calendar = google.calendar('v3');
        const auth = new google.auth.OAuth2();

        auth.setCredentials({
          access_token: accessToken,
        });

        // Get events for the entire day
        const response = await calendar.events.list({
          auth,
          calendarId: 'primary',
          timeMin: formatISO(startOfDay(date)),
          timeMax: formatISO(endOfDay(date)),
          singleEvents: true,
          orderBy: 'startTime',
          maxResults: 50,
        });

        const events = response.data.items || [];

        return {
          date: formatISO(date, { representation: 'date' }),
          eventsCount: events.length,
          events: events.map((event) => ({
            id: event.id,
            summary: event.summary || 'No title',
            description: event.description,
            startTime: event.start?.dateTime || event.start?.date,
            endTime: event.end?.dateTime || event.end?.date,
            location: event.location,
            attendees:
              event.attendees?.map((attendee) => ({
                email: attendee.email,
                name: attendee.displayName,
                responseStatus: attendee.responseStatus,
              })) || [],
            status: event.status,
            htmlLink: event.htmlLink,
          })),
        };
      } catch (error) {
        if (error instanceof GaxiosError) {
          if (error.status === 401) {
            throw new FederatedConnectionError(`Authorization required to access the Federated Connection`);
          }
        }

        throw error;
      }
    },
  }),
);
You need to obtain an API Key from OpenAI or another provider to use an LLM. Add the API key to your environment variables:
.env.local
# ...
# You can use any provider of your choice supported by Vercel AI
OPENAI_API_KEY="YOUR_API_KEY"

Add step up authorization

When you try to use the tool, the application requests any additional Google scopes that are required but not yet authorized. This process is called step-up authorization.Let us implement step-up authorization.Install Auth0 AI Components for Next.js to get the required UI components.
npx @auth0/ai-components add FederatedConnections
Add a new file, src/components/auth0-ai/FederatedConnections/FederatedConnectionInterruptHandler.tsx with the following code:
src/components/auth0-ai/FederatedConnections/FederatedConnectionInterruptHandler.tsx
import { FederatedConnectionInterrupt } from "@auth0/ai/interrupts";
import type { Auth0InterruptionUI } from "@auth0/ai-vercel/react";

import { EnsureAPIAccess } from "@/components/auth0-ai/FederatedConnections";

interface FederatedConnectionInterruptHandlerProps {
  interrupt: Auth0InterruptionUI | null;
}

export function FederatedConnectionInterruptHandler({
  interrupt,
}: FederatedConnectionInterruptHandlerProps) {
  if (!FederatedConnectionInterrupt.isInterrupt(interrupt)) {
    return null;
  }

  return (
    <div key={interrupt.name} className="whitespace-pre-wrap">
      <EnsureAPIAccess
        mode="popup"
        interrupt={interrupt}
        connectWidget={{
          title: "Authorization Required.",
          description: interrupt.message,
          action: { label: "Authorize" },
        }}
      />
    </div>
  );
}
Now, update the src/components/chat-window.tsx file to include the FederatedConnectionInterruptHandler component:
src/components/chat-window.tsx
//...
import { useInterruptions } from '@auth0/ai-vercel/react';
import { FederatedConnectionInterruptHandler } from '@/components/auth0-ai/FederatedConnections/FederatedConnectionInterruptHandler';


//... existing code
export function ChatWindow(props: {
  //... existing code
}) {
  const chat = useInterruptions((handler) =>
    useChat({
      api: props.endpoint,
      onError: handler((e: Error) => {
        console.error('Error: ', e);
        toast.error(`Error while processing your request`, { description: e.message });
      }),
    }),
  );

  //... existing code
  return (
    <StickToBottom>
      <StickyToBottomContent
        className="absolute inset-0"
        contentClassName="py-8 px-2"
        content={
          chat.messages.length === 0 ? (
            <div>{props.emptyStateComponent}</div>
          ) : (
            <>
              <ChatMessages
                aiEmoji={props.emoji}
                messages={chat.messages}
                emptyStateComponent={props.emptyStateComponent}
              />
              <div className="flex flex-col max-w-[768px] mx-auto pb-12 w-full">
                <FederatedConnectionInterruptHandler interrupt={chat.toolInterrupt} />
              </div>
            </>
          )
        }
        {/* ... existing code */}
      ></StickyToBottomContent>
    </StickToBottom>
  );
}

Add the tool to the AI agent

Handle the interrupts from the Agent and call the tool from your AI app to get calendar events. Update the /src/app/api/chat/route.ts file with the following code:
src/app/api/chat/route.ts
//...
import { setAIContext } from "@auth0/ai-vercel";
import {
  errorSerializer,
  withInterruptions,
} from "@auth0/ai-vercel/interrupts";
import { getCalendarEventsTool } from "@/lib/tools/google-calendar";
//... existing code

export async function POST(req: NextRequest) {
  const request = await req.json();
  const messages = sanitizeMessages(request.messages);

  setAIContext({ threadID: request.id });

  const tools = {
    getCalendarEventsTool,
  };

  return createDataStreamResponse({
    execute: withInterruptions(
      async (dataStream: DataStreamWriter) => {
        const result = streamText({
          model: openai("gpt-4o-mini"),
          system: AGENT_SYSTEM_TEMPLATE,
          messages,
          maxSteps: 5,
          tools,
        });

        result.mergeIntoDataStream(dataStream, {
          sendReasoning: true,
        });
      },
      {
        messages,
        tools,
      }
    ),
    onError: errorSerializer((err: any) => {
      console.log(err);
      return `An error occurred! ${err.message}`;
    }),
  });
}

Test your application

Start the application with npm run dev. Then, navigate to http://localhost:3000. If you have already logged in, make sure to log out and log back in using Google. Then, ask your AI Agent a question about your calendar!That’s it! You successfully integrated external tool-calling into your project.Explore the example app on GitHub.

Next steps

You have successfully added the ability to get access tokens for tool calling to your application. For next steps: