Scalekit handles the full OAuth lifecycle — authorization, token storage, and refresh — so agents can act on behalf of users in Gmail, Slack, Notion, Calendar, and other connectors.
Required env vars: SCALEKIT_CLIENT_ID, SCALEKIT_CLIENT_SECRET, SCALEKIT_ENVIRONMENT_URL
→ Get from app.scalekit.com: Developers → Settings → API Credentials
→ Some docs/samples use SCALEKIT_ENV_URL for the same URL value; in this skill use SCALEKIT_ENVIRONMENT_URL.
Key concept — connection name: Every connector has a dashboard Connection Name — the exact string set when creating the connection. Pass it in every SDK call: Python connection_name=..., Node connectionName: '...'. It may differ from the connector slug (e.g. slug "gmail" but name "MY_GMAIL_PROD"). Always use the dashboard value, never invent a slug.
Guardrails
- MUST pass the exact dashboard Connection Name in every SDK call (
connection_namein Python,connectionNamein Node) — never guess it from the connector slug, and never use aconnectorfield for that value. - MUST read credentials from
SCALEKIT_CLIENT_ID/SCALEKIT_CLIENT_SECRET/SCALEKIT_ENVIRONMENT_URLenv vars; MUST NOT hardcode secrets in source. - MUST NOT create authorization links for any non-Gmail connector before it is configured in the dashboard — the call will fail.
Setup
Install the SDK and initialize the client:
Important: Except for Gmail, all connectors must be configured in the Scalekit Dashboard first before creating authorization URLs.
To set up a connector: Scalekit Dashboard → AgentKit → Connections → + Create Connection → Select connector → Set Connection Name → Save
Python
pip install scalekit-sdk-python python-dotenv requests
from scalekit import ScalekitClient
import os
from dotenv import load_dotenv
load_dotenv()
sk_client = ScalekitClient(
client_id=os.getenv("SCALEKIT_CLIENT_ID"),
client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"),
)
actions = sk_client.actions
Node.js
npm install @scalekit-sdk/node
import { ScalekitClient } from '@scalekit-sdk/node';
import 'dotenv/config';
const scalekitClient = new ScalekitClient(
process.env.SCALEKIT_ENVIRONMENT_URL!,
process.env.SCALEKIT_CLIENT_ID!,
process.env.SCALEKIT_CLIENT_SECRET!
);
const { connectedAccounts } = scalekitClient;
Integration workflow
Gmail works without dashboard setup. All other connectors must be configured first: Dashboard → AgentKit → Connections → + Create Connection. The Connection Name in the dashboard must match
connection_namein code exactly.
Copy this checklist:
AgentKit Integration Progress:
- [ ] Step 1: SDK installed and client initialized
- [ ] Step 2: Connected account created for the user
- [ ] Step 3: User has authorized the connection (status = ACTIVE)
- [ ] Step 4: Access token fetched successfully
- [ ] Step 5: Downstream API call succeeds with fetched token
Step 1 — Create a connected account
Replace "user_123" with the project's actual user ID. Replace "gmail" with the dashboard Connection Name (not necessarily the connector slug).
Python
response = actions.get_or_create_connected_account(
connection_name="gmail",
identifier="user_123"
)
connected_account = response.connected_account
Node.js
const response = await connectedAccounts.getOrCreateConnectedAccount({
connectionName: 'gmail',
identifier: 'user_123',
});
const connectedAccount = response.connectedAccount;
Step 2 — Authorize the user
If status is not ACTIVE, the user must complete OAuth. In a web app, redirect to link. In CLI/dev, print and wait.
Python
import sys
if connected_account.status != "ACTIVE":
link_response = actions.get_authorization_link(
connection_name="gmail",
identifier="user_123"
)
print("Authorize here:", link_response.link)
# Non-interactive/agent: print link and stop; re-run from Step 3 after user OAuth.
if not sys.stdin.isatty():
print("Complete OAuth in a browser, then re-run from Step 3 (fetch tokens).")
raise SystemExit(0)
input("Press Enter after authorizing...")
Node.js
// Place this import at module top-level (not inside the if):
import * as readline from 'node:readline/promises';
if (connectedAccount?.status !== 'ACTIVE') {
const linkResponse = await connectedAccounts.getMagicLinkForConnectedAccount({
connectionName: 'gmail',
identifier: 'user_123',
});
console.log('Authorize here:', linkResponse.link);
// Web app: redirect the browser to linkResponse.link, then continue after callback.
// Non-interactive/agent: print the link and stop — re-run from Step 3 after OAuth.
if (!process.stdin.isTTY) {
console.log('Complete OAuth in a browser, then re-run from Step 3 (fetch tokens).');
// return; // or process.exit(0) in a one-shot script
} else {
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
await rl.question('Press Enter after authorizing…');
rl.close();
}
}
Step 3 — Fetch OAuth tokens
ALWAYS call get_connected_account immediately before any API call — Scalekit auto-refreshes tokens and this guarantees the latest valid token.
Python
response = actions.get_connected_account(
connection_name="gmail",
identifier="user_123"
)
tokens = response.connected_account.authorization_details["oauth_token"]
access_token = tokens["access_token"]
refresh_token = tokens["refresh_token"]
Node.js
const accountResponse = await connectedAccounts.getConnectedAccountByIdentifier({
connectionName: 'gmail',
identifier: 'user_123',
});
// authorizationDetails is a oneof: when case is 'oauthToken', value holds the tokens
const authDetails = accountResponse?.connectedAccount?.authorizationDetails;
const oauth = authDetails?.details?.case === 'oauthToken'
? authDetails.details.value
: undefined;
const accessToken = oauth?.accessToken;
const refreshToken = oauth?.refreshToken;
Step 4 — Call the third-party API (token path)
This step uses the raw OAuth access token against the provider’s HTTP API. For framework tool calling (LangChain / Google ADK), see Building agents below; for catalog/schema discovery, switch to discovering-connector-tools.
Use access_token from Step 3 as a Bearer token. Example: fetch 5 unread Gmail messages.
Python
import requests
headers = {"Authorization": f"Bearer {access_token}"}
list_url = "https://gmail.googleapis.com/gmail/v1/users/me/messages"
messages = requests.get(
list_url, headers=headers, params={"q": "is:unread", "maxResults": 5}
).json().get("messages", [])
for msg in messages:
data = requests.get(
f"{list_url}/{msg['id']}", headers=headers,
params={"format": "metadata", "metadataHeaders": ["From", "Subject", "Date"]}
).json()
hdrs = data.get("payload", {}).get("headers", [])
print(next((h["value"] for h in hdrs if h["name"] == "Subject"), "No Subject"))
print(next((h["value"] for h in hdrs if h["name"] == "From"), "Unknown"))
print(data.get("snippet", ""))
print("-" * 50)
Node.js
const listUrl = 'https://gmail.googleapis.com/gmail/v1/users/me/messages';
const params = new URLSearchParams({ q: 'is:unread', maxResults: '5' });
const { messages = [] } = await fetch(`${listUrl}?${params}`, {
headers: { Authorization: `Bearer ${accessToken}` },
}).then(r => r.json());
for (const msg of messages) {
const msgData = await fetch(
`${listUrl}/${msg.id}?format=metadata&metadataHeaders=From&metadataHeaders=Subject&metadataHeaders=Date`,
{ headers: { Authorization: `Bearer ${accessToken}` } }
).then(r => r.json());
const h = msgData.payload?.headers ?? [];
console.log('Subject:', h.find(x => x.name === 'Subject')?.value ?? 'No Subject');
console.log('From:', h.find(x => x.name === 'From')?.value ?? 'Unknown');
console.log('Snippet:', msgData.snippet ?? '');
console.log('-'.repeat(50));
}
Adapting to other connectors
Replace the Connection Name value ("gmail" in the examples) with the dashboard name for that connection (e.g. "slack", "MY_NOTION_PROD"). Configure non-Gmail connectors in the dashboard first.
The SDK workflow (Steps 1–3) is identical for all connectors. Only the downstream API call (Step 4) changes.
For connector-specific API details, see the Scalekit Connectors catalog.
Building agents
Use Scalekit tools with AI frameworks to build agents that can execute actions on behalf of users. Install the framework packages first; the Scalekit SDK alone is not enough for these snippets.
Language note: LangChain Tools + Google ADK helpers below are Python-first in the Scalekit SDK today. For Node, use the token path (Steps 1–4) or expose tools via MCP (
exposing-agentkit-via-mcp) and bind them in your Node agent framework.
LangChain agents
Create conversational agents with LangChain that can autonomously call Scalekit tools based on user intent.
Python
pip install scalekit-sdk-python langchain langchain-openai langchain-core
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_core.prompts import ChatPromptTemplate
# providers = connector type slug for tool discovery (GMAIL, SLACK, …).
# This is NOT the dashboard Connection Name used in Steps 1–3.
tools = actions.langchain.get_tools(
identifier="user_123",
providers=["GMAIL"],
page_size=100
)
# Define the agent prompt
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant with access to external tools."),
("placeholder", "{chat_history}"),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"),
])
# Create and run the agent
llm = ChatOpenAI(model="gpt-4o")
agent = create_openai_tools_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
result = executor.invoke({"input": "fetch my last 5 unread emails and summarize them"})
Google ADK agents
Build agents using Google's Agent Development Kit with native Gemini integration.
Python
# Package: https://pypi.org/project/google-adk/ (Google Agent Development Kit)
pip install scalekit-sdk-python google-adk
from google.adk.agents import Agent
# providers = connector type slug (not the dashboard Connection Name from Steps 1–3)
gmail_tools = actions.google.get_tools(
providers=["GMAIL"],
identifier="user_123",
page_size=100
)
# Create the agent
agent = Agent(
name="gmail_assistant",
model="gemini-2.5-flash",
description="Gmail assistant that can read and manage emails",
instruction="You are a helpful Gmail assistant that can read, send, and organize emails.",
tools=gmail_tools
)
# Run the agent
response = agent.process_request("fetch my last 5 unread emails and summarize them")
For more examples and framework-specific patterns, see the AgentKit code samples.
Deep reference
- AgentKit overview: docs.scalekit.com/agentkit/overview
- Connections: docs.scalekit.com/agentkit/connections
- Connected accounts: docs.scalekit.com/agentkit/connected-accounts
- Tool discovery: docs.scalekit.com/agentkit/tool-discovery
- Connectors catalog: docs.scalekit.com/agentkit/connectors
- BYOC (Bring Your Own Credentials): docs.scalekit.com/agentkit/byoc
When to switch skills
- Use
discovering-connector-toolswhen the user needs the current tool catalog or schema. - Use the Scalekit MCP server (
https://mcp.scalekit.com) to validate a tool call interactively. - Use
exposing-agentkit-via-mcpwhen the user wants AgentKit tools exposed over MCP.