Partner Guide
Use the SDK to manage connected accounts and act on behalf of your users with client.asAccount().
Partner Guide
Partners (platforms, SaaS apps) use a single API key to manage many end-user accounts. The SDK provides two distinct surfaces for this:
| Surface | Access via | Purpose |
|---|---|---|
| Management plane | client.accounts.* | Create accounts, initiate OAuth, manage integrations |
| Data plane | client.asAccount(externalId) | Fetch tools/skills and make API calls scoped to a user |
Setup
import { supyagent } from '@supyagent/sdk';
const client = supyagent({ apiKey: process.env.SUPYAGENT_API_KEY! });Managing Accounts
Use client.accounts to create and manage connected accounts. These methods never require an X-Account-Id header — they operate on your partner-level API key.
// Create an account for one of your users
const account = await client.accounts.create({
externalId: 'user_123',
displayName: 'Jane Smith',
metadata: { plan: 'pro' },
});
// List all accounts
const { accounts, total } = await client.accounts.list({ limit: 50 });
// Get account with integrations
const details = await client.accounts.get(account.id);
console.log(details.integrations); // [{ provider: 'google', status: 'active', ... }]OAuth Connect Flow
Initiate an OAuth session for a connected account, then redirect the user:
const session = await client.accounts.connect(account.id, {
provider: 'google',
redirectUrl: 'https://yourapp.com/callback',
scopes: ['gmail.read', 'calendar.read'],
});
// Redirect user to session.connectUrlCheck the session status after the user returns:
const status = await client.accounts.getSession(account.id, session.sessionId);
if (status.status === 'completed') {
console.log(`${status.provider} connected successfully`);
}If you're using React, see the React hooks for useSupyagentConnect() and <ConnectCallback>.
Acting on Behalf of Users
Once a user has connected integrations, use client.asAccount() to fetch tools and skills scoped to that user. Every request from the scoped client automatically includes the X-Account-Id header.
const userClient = client.asAccount('user_123');
// Fetch tools scoped to this user's integrations
const tools = await userClient.tools({ cache: 300 });
// Or use skills (more token-efficient)
const { systemPrompt, tools: skillTools } = await userClient.skills({ cache: 300 });
// Check the user's account info
const me = await userClient.me();The scoped client has tools(), skills(), and me() — but not accounts or asAccount(). Management stays on the parent client; nesting is not allowed.
Each scoped client has its own cache, separate from the parent and other scoped clients.
Using with Vercel AI SDK
import { streamText } from 'ai';
import { supyagent } from '@supyagent/sdk';
import { openai } from '@ai-sdk/openai';
const client = supyagent({ apiKey: process.env.SUPYAGENT_API_KEY! });
export async function POST(req: Request) {
const { messages, userId } = await req.json();
// Get tools scoped to this user
const userClient = client.asAccount(userId);
const { systemPrompt, tools } = await userClient.skills({ cache: 300 });
const result = streamText({
model: openai('gpt-4o'),
system: `You are a helpful assistant.\n\n${systemPrompt}`,
messages,
tools,
});
return result.toDataStreamResponse();
}Full Next.js Example
End-to-end flow: create account, initiate OAuth, then use scoped tools.
import { NextRequest, NextResponse } from 'next/server';
import { supyagent } from '@supyagent/sdk';
const client = supyagent({ apiKey: process.env.SUPYAGENT_API_KEY! });
export async function POST(request: NextRequest) {
const { userId, provider } = await request.json();
// 1. Create or look up the connected account
let account;
try {
account = await client.accounts.create({ externalId: userId });
} catch {
// Account already exists — look it up
const { accounts } = await client.accounts.list();
account = accounts.find((a) => a.externalId === userId);
}
if (!account) {
return NextResponse.json({ error: 'Account not found' }, { status: 404 });
}
// 2. Create a connect session
const session = await client.accounts.connect(account.id, {
provider,
redirectUrl: `${process.env.NEXT_PUBLIC_APP_URL}/integrations/callback`,
});
return NextResponse.json({ connectUrl: session.connectUrl });
}import { streamText } from 'ai';
import { supyagent } from '@supyagent/sdk';
import { openai } from '@ai-sdk/openai';
const client = supyagent({ apiKey: process.env.SUPYAGENT_API_KEY! });
export async function POST(req: Request) {
const { messages, userId } = await req.json();
// Scoped to the user's integrations
const userClient = client.asAccount(userId);
const tools = await userClient.tools({ cache: 300 });
const result = streamText({
model: openai('gpt-4o'),
messages,
tools,
});
return result.toDataStreamResponse();
}