Agent Auth - Quickstart Guide
Get started with Agent Auth in minutes. Learn how to create your first connection, authenticate users, and execute tools.
Agent Auth will help enable your AI Agents to take actions in real world applications on behalf of your users. Scalekit automatically handles authorizing your users to grant access to third party applications like Gmail, Calendar, Slack, Notion etc and using our pre-built connectors, lets your AI Agent execute actions like fetching emails, creating calendar events, updating notion pages, sending alerts via Slack etc.
This quickstart guide will show you how to get started with Agent Auth in just a few minutes. You’ll learn how to set up connections, authenticate users, and fetch tokens for your users
What you’ll build
Section titled “What you’ll build”In this quickstart, you’ll build a simple tool calling program that:
- Authenticates a user with GMail to authenticate their Gmail account via OAuth 2.0
- Fetches last 5 unread emails from the user’s inbox
Prerequisites
Section titled “Prerequisites”Before you start, make sure you have:
- Scalekit API credentials (Client ID and Client Secret)
- Development environment (Node.js, Python, or similar)
Step 1: Set up your environment
Section titled “Step 1: Set up your environment”First, install the Scalekit Python SDK and initialize the client with your API credentials: Get Your credentials from Scalekit dashboard at app.scalekit.com Developers-> Settings -> API Credentials
pip install scalekit-sdk-pythonnpm install @scalekit-sdk/node@2.2.0-beta.1import scalekit.clientimport osfrom dotenv import load_dotenvload_dotenv()
scalekit = scalekit.client.ScalekitClient( client_id=os.getenv("SCALEKIT_CLIENT_ID"), client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), env_url=os.getenv("SCALEKIT_ENV_URL"),)actions = scalekit.actionsimport { ScalekitClient } from '@scalekit-sdk/node';import 'dotenv/config';
const scalekitClient = new ScalekitClient( process.env.SCALEKIT_ENV_URL, process.env.SCALEKIT_CLIENT_ID, process.env.SCALEKIT_CLIENT_SECRET);
const { connectedAccounts, tools } = scalekitClient;Step 2: Create a connected account
Section titled “Step 2: Create a connected account”Let’s authorize a user to access their Gmail account by creating a connected account. This represents the user’s connection to their Gmail account:
# Create a connected account for user if it doesn't exist alreadyresponse = actions.get_or_create_connected_account( connection_name="gmail", identifier="user_123" #unique identifier for your connected account. can be replaced with your system's user ID)connected_account = response.connected_accountprint(f'Connected account created: {connected_account.id}')// Create a connected account for user if it doesn't exist alreadyconst response = await connectedAccounts.getOrCreateConnectedAccount({ connector: 'gmail', identifier: 'user_123', // unique identifier for your connected account. can be replaced with your system's user ID});
const connectedAccount = response.connectedAccount;console.log('Connected account created:', connectedAccount?.id);Step 3: Authenticate the user
Section titled “Step 3: Authenticate the user”Inorder to execute any tools on behalf of the user, the user first needs to grant authorization to access their gmail account. Scalekit automatically handles the entire OAuth workflow with the Gmail provider, gets the access token, refreshes the access token periodically based on the refresh token etc.
If the user’s access token is expired, Scalekit will automatically refresh the access token using the refresh token. At any time, you can check the authorization status of the connected account and determine if the user needs to re-authorize the connection.
# If the user hasn't yet authorized the gmail connection or if the user's access token is expired, generate a link for them to authorize the connectionif(connected_account.status != "ACTIVE"): print(f"gmail is not connected: {connected_account.status}") link_response = actions.get_authorization_link( connection_name="gmail", identifier="user_123" ) print(f"🔗click on the link to authorize gmail", link_response.link) input(f"⎆ Press Enter after authorizing gmail...")
# In a real app, redirect the user to this URL so that the user can complete the authentication process for their gmail account// If the user hasn't yet authorized the gmail connection or if the user's access token is expired, generate a link for them to authorize the connectionif (connectedAccount?.status !== 'ACTIVE') { console.log('gmail is not connected:', connectedAccount?.status); const linkResponse = await connectedAccounts.getMagicLinkForConnectedAccount({ connector: 'gmail', identifier: 'user_123', }); console.log('🔗 click on the link to authorize gmail', linkResponse.link); // In a real app, redirect the user to this URL so that the user can complete the authentication process for their gmail account}Step 4: Fetch oauth tokens for your user
Section titled “Step 4: Fetch oauth tokens for your user”Now that the user has successfully authorized the gmail connection, You can fetch the latest access token and refresh token for the user’s connected account anytime you want. scalekit will keep the token refreshed periodically so that you always have the latest valid access token to make API calls on behalf of the user.
# Fetch recent emailsresponse = actions.get_connected_account( connection_name="gmail", identifier="user_123")
connected_account = response.connected_account
tokens = connected_account.authorization_details["oauth_token"]access_token = tokens["access_token"]refresh_token = tokens["refresh_token"]
print("access token:",access_token)print("refresh token:",refresh_token)const accountResponse = await connectedAccounts.getConnectedAccountByIdentifier({ connector: 'gmail', identifier: 'user@example.com',});
const authDetails = accountResponse?.connectedAccount?.authorizationDetails;const accessToken = (authDetails && authDetails.details?.case === "oauthToken") ? authDetails.details.value?.accessToken : undefined;const refreshToken = (authDetails && authDetails.details?.case === "oauthToken") ? authDetails.details.value?.refreshToken : undefined;
console.log('Connected account:', accountResponse);console.log('accessToken:', accessToken);console.log('refreshToken:', refreshToken);Step 5: Call the Google Gmail API to fetch last 5 unread emails
Section titled “Step 5: Call the Google Gmail API to fetch last 5 unread emails”Now that the user is authenticated and you have the access token, you can execute the Gmail API to fetch the last 5 unread emails from the user’s inbox. Below example directly calls the Gmail API. but use the gmail SDK or any other HTTP client of your choice to make the API calls.
# Fetch 5 unread emails using Gmail APIheaders = { "Authorization": f"Bearer {access_token}", #use the access token obtained above}
list_url = "https://gmail.googleapis.com/gmail/v1/users/me/messages"params = { "q": "is:unread", "maxResults": 5,}
list_response = requests.get(list_url, headers=headers, params=params)messages = list_response.json().get("messages", [])
print(f"\nFound {len(messages)} unread emails:\n")
#fetch details for each email and print themfor msg in messages: msg_url = f"{list_url}/{msg['id']}" msg_response = requests.get(msg_url, headers=headers, params={"format": "metadata", "metadataHeaders": ["From", "Subject", "Date"]}) msg_data = msg_response.json()
headers_list = msg_data.get("payload", {}).get("headers", []) subject = next((h["value"] for h in headers_list if h["name"] == "Subject"), "No Subject") sender = next((h["value"] for h in headers_list if h["name"] == "From"), "Unknown") date = next((h["value"] for h in headers_list if h["name"] == "Date"), "Unknown")
print(f"From: {sender}") print(f"Subject: {subject}") print(f"Date: {date}") print(f"Snippet: {msg_data.get('snippet', '')}") print("-" * 50)// Fetch 5 unread emails using Gmail APIconst listUrl = 'https://gmail.googleapis.com/gmail/v1/users/me/messages';const params = new URLSearchParams({ q: 'is:unread', maxResults: '5' });
const listResponse = await fetch(`${listUrl}?${params}`, { headers: { Authorization: `Bearer ${accessToken}` }, // use the access token obtained above});const listData = await listResponse.json();const messages = listData.messages ?? [];
console.log(`\nFound ${messages.length} unread emails:\n`);
// fetch details for each email and print themfor (const msg of messages) { const msgResponse = await fetch( `${listUrl}/${msg.id}?format=metadata&metadataHeaders=From&metadataHeaders=Subject&metadataHeaders=Date`, { headers: { Authorization: `Bearer ${accessToken}` } } ); const msgData = await msgResponse.json();
const headersList = msgData.payload?.headers ?? []; const subject = headersList.find((h) => h.name === 'Subject')?.value ?? 'No Subject'; const sender = headersList.find((h) => h.name === 'From')?.value ?? 'Unknown'; const date = headersList.find((h) => h.name === 'Date')?.value ?? 'Unknown';
console.log(`From: ${sender}`); console.log(`Subject: ${subject}`); console.log(`Date: ${date}`); console.log(`Snippet: ${msgData.snippet ?? ''}`); console.log('-'.repeat(50));}Congratulations!
Section titled “Congratulations!”Congratulations! You’ve successfully implemented a program that executes API on behalf of a user using Agent Auth. This can be extended to any number of connections and scalekit will handle the authentication and token management for you.