Code Examples
TypeScript, Python, and cURL examples for every Connected Accounts API operation — with reusable helpers and end-to-end integration patterns.
Code Examples
Complete examples for every API operation in TypeScript, Python, and cURL. Start with the helper functions to reduce boilerplate, then see examples for each operation.
Helper Functions
Reusable wrappers that handle authentication, error checking, and the X-Account-Id header pattern.
const BASE_URL = "https://app.supyagent.com/api/v1";
class SupyagentClient {
constructor(private apiKey: string) {}
private async request<T>(
path: string,
options: RequestInit = {},
accountId?: string
): Promise<T> {
const headers: Record<string, string> = {
"Authorization": `Bearer ${this.apiKey}`,
"Content-Type": "application/json",
...(options.headers as Record<string, string>),
};
if (accountId) {
headers["X-Account-Id"] = accountId;
}
const response = await fetch(`${BASE_URL}${path}`, {
...options,
headers,
});
const data = await response.json();
if (!response.ok || !data.ok) {
throw new Error(data.error || `Request failed: ${response.status}`);
}
return data.data;
}
// --- Accounts ---
async createAccount(params: {
external_id: string;
display_name?: string;
metadata?: Record<string, unknown>;
}) {
return this.request("/accounts", {
method: "POST",
body: JSON.stringify(params),
});
}
async listAccounts(limit = 20, offset = 0) {
return this.request(`/accounts?limit=${limit}&offset=${offset}`);
}
async getAccount(accountId: string) {
return this.request(`/accounts/${accountId}`);
}
async updateAccount(
accountId: string,
params: { display_name?: string; metadata?: Record<string, unknown> }
) {
return this.request(`/accounts/${accountId}`, {
method: "PATCH",
body: JSON.stringify(params),
});
}
async deleteAccount(accountId: string) {
return this.request(`/accounts/${accountId}`, { method: "DELETE" });
}
// --- Connect Sessions ---
async createConnectSession(
accountId: string,
params: { provider: string; redirect_url: string; scopes?: string[] }
) {
return this.request(`/accounts/${accountId}/connect`, {
method: "POST",
body: JSON.stringify(params),
});
}
async getConnectSession(accountId: string, sessionId: string) {
return this.request(`/accounts/${accountId}/connect/${sessionId}`);
}
// --- Integrations ---
async listIntegrations(accountId: string) {
return this.request(`/accounts/${accountId}/integrations`);
}
async disconnectProvider(accountId: string, provider: string) {
return this.request(
`/accounts/${accountId}/integrations/${provider}`,
{ method: "DELETE" }
);
}
// --- Provider API Calls ---
async providerGet(path: string, externalId: string) {
return this.request(path, {}, externalId);
}
async providerPost(
path: string,
externalId: string,
body: Record<string, unknown>
) {
return this.request(
path,
{ method: "POST", body: JSON.stringify(body) },
externalId
);
}
}
// Usage
const client = new SupyagentClient("sk_live_your_key_here");import requests
BASE_URL = "https://app.supyagent.com/api/v1"
class SupyagentClient:
def __init__(self, api_key: str):
self.api_key = api_key
self.session = requests.Session()
self.session.headers.update({
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
})
def _request(self, method: str, path: str, account_id: str | None = None, **kwargs):
headers = {}
if account_id:
headers["X-Account-Id"] = account_id
response = self.session.request(
method, f"{BASE_URL}{path}", headers=headers, **kwargs
)
data = response.json()
if not response.ok or not data.get("ok"):
raise Exception(data.get("error", f"Request failed: {response.status_code}"))
return data["data"]
# --- Accounts ---
def create_account(self, external_id: str, display_name: str | None = None,
metadata: dict | None = None):
return self._request("POST", "/accounts", json={
"external_id": external_id,
"display_name": display_name,
"metadata": metadata or {},
})
def list_accounts(self, limit: int = 20, offset: int = 0):
return self._request("GET", f"/accounts?limit={limit}&offset={offset}")
def get_account(self, account_id: str):
return self._request("GET", f"/accounts/{account_id}")
def update_account(self, account_id: str, **kwargs):
return self._request("PATCH", f"/accounts/{account_id}", json=kwargs)
def delete_account(self, account_id: str):
return self._request("DELETE", f"/accounts/{account_id}")
# --- Connect Sessions ---
def create_connect_session(self, account_id: str, provider: str,
redirect_url: str, scopes: list[str] | None = None):
return self._request("POST", f"/accounts/{account_id}/connect", json={
"provider": provider,
"redirect_url": redirect_url,
**({"scopes": scopes} if scopes else {}),
})
def get_connect_session(self, account_id: str, session_id: str):
return self._request("GET", f"/accounts/{account_id}/connect/{session_id}")
# --- Integrations ---
def list_integrations(self, account_id: str):
return self._request("GET", f"/accounts/{account_id}/integrations")
def disconnect_provider(self, account_id: str, provider: str):
return self._request("DELETE", f"/accounts/{account_id}/integrations/{provider}")
# --- Provider API Calls ---
def provider_get(self, path: str, external_id: str):
return self._request("GET", path, account_id=external_id)
def provider_post(self, path: str, external_id: str, body: dict):
return self._request("POST", path, account_id=external_id, json=body)
# Usage
client = SupyagentClient("sk_live_your_key_here")Account Management
Create an Account
curl -X POST https://app.supyagent.com/api/v1/accounts \
-H "Authorization: Bearer sk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"external_id": "user-123",
"display_name": "Jane Smith",
"metadata": { "plan": "pro", "company": "Acme Corp" }
}'const account = await client.createAccount({
external_id: "user-123",
display_name: "Jane Smith",
metadata: { plan: "pro", company: "Acme Corp" },
});
console.log(account.id); // "550e8400-..."
console.log(account.external_id); // "user-123"account = client.create_account(
external_id="user-123",
display_name="Jane Smith",
metadata={"plan": "pro", "company": "Acme Corp"},
)
print(account["id"]) # "550e8400-..."
print(account["external_id"]) # "user-123"List Accounts
# Default pagination (limit=20, offset=0)
curl https://app.supyagent.com/api/v1/accounts \
-H "Authorization: Bearer sk_live_your_key_here"
# Custom pagination
curl "https://app.supyagent.com/api/v1/accounts?limit=50&offset=100" \
-H "Authorization: Bearer sk_live_your_key_here"const { accounts, total } = await client.listAccounts(50, 0);
console.log(`${total} accounts total`);
for (const account of accounts) {
console.log(`${account.external_id}: ${account.display_name}`);
}result = client.list_accounts(limit=50, offset=0)
print(f"{result['total']} accounts total")
for account in result["accounts"]:
print(f"{account['external_id']}: {account['display_name']}")Get Account Details
curl https://app.supyagent.com/api/v1/accounts/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer sk_live_your_key_here"const account = await client.getAccount("550e8400-e29b-41d4-a716-446655440000");
console.log(account.display_name);
console.log(account.integrations); // List of connected providersaccount = client.get_account("550e8400-e29b-41d4-a716-446655440000")
print(account["display_name"])
print(account["integrations"]) # List of connected providersUpdate an Account
curl -X PATCH https://app.supyagent.com/api/v1/accounts/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer sk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"display_name": "Jane Doe",
"metadata": { "plan": "enterprise" }
}'const updated = await client.updateAccount(
"550e8400-e29b-41d4-a716-446655440000",
{
display_name: "Jane Doe",
metadata: { plan: "enterprise" },
}
);updated = client.update_account(
"550e8400-e29b-41d4-a716-446655440000",
display_name="Jane Doe",
metadata={"plan": "enterprise"},
)Delete an Account
Deleting an account cascades to all integrations and stored tokens. This cannot be undone.
curl -X DELETE https://app.supyagent.com/api/v1/accounts/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer sk_live_your_key_here"await client.deleteAccount("550e8400-e29b-41d4-a716-446655440000");client.delete_account("550e8400-e29b-41d4-a716-446655440000")OAuth Connect Sessions
Start a Connect Session
curl -X POST https://app.supyagent.com/api/v1/accounts/550e8400-e29b-41d4-a716-446655440000/connect \
-H "Authorization: Bearer sk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"provider": "google",
"redirect_url": "https://yourapp.com/callback"
}'const session = await client.createConnectSession(
"550e8400-e29b-41d4-a716-446655440000",
{
provider: "google",
redirect_url: "https://yourapp.com/callback",
}
);
// Redirect the user to session.connect_url
console.log(session.connect_url);
console.log(session.session_id);
console.log(session.expires_at);session = client.create_connect_session(
"550e8400-e29b-41d4-a716-446655440000",
provider="google",
redirect_url="https://yourapp.com/callback",
)
# Redirect the user to session["connect_url"]
print(session["connect_url"])
print(session["session_id"])
print(session["expires_at"])Check Session Status
curl https://app.supyagent.com/api/v1/accounts/550e8400-e29b-41d4-a716-446655440000/connect/660e8400-e29b-41d4-a716-446655440001 \
-H "Authorization: Bearer sk_live_your_key_here"const session = await client.getConnectSession(
"550e8400-e29b-41d4-a716-446655440000",
"660e8400-e29b-41d4-a716-446655440001"
);
if (session.status === "completed") {
console.log(`${session.provider} connected successfully`);
}session = client.get_connect_session(
"550e8400-e29b-41d4-a716-446655440000",
"660e8400-e29b-41d4-a716-446655440001",
)
if session["status"] == "completed":
print(f"{session['provider']} connected successfully")Integration Management
List Integrations
curl https://app.supyagent.com/api/v1/accounts/550e8400-e29b-41d4-a716-446655440000/integrations \
-H "Authorization: Bearer sk_live_your_key_here"const { integrations } = await client.listIntegrations(
"550e8400-e29b-41d4-a716-446655440000"
);
for (const integration of integrations) {
console.log(`${integration.provider}: ${integration.status}`);
}result = client.list_integrations("550e8400-e29b-41d4-a716-446655440000")
for integration in result["integrations"]:
print(f"{integration['provider']}: {integration['status']}")Disconnect a Provider
curl -X DELETE https://app.supyagent.com/api/v1/accounts/550e8400-e29b-41d4-a716-446655440000/integrations/slack \
-H "Authorization: Bearer sk_live_your_key_here"await client.disconnectProvider(
"550e8400-e29b-41d4-a716-446655440000",
"slack"
);client.disconnect_provider("550e8400-e29b-41d4-a716-446655440000", "slack")Provider API Calls
All provider calls use the X-Account-Id header with the account's external_id. See Making API Calls for the full pattern.
Using @supyagent/sdk (Recommended)
If you're using the Node.js SDK, the client.asAccount() method handles the X-Account-Id header automatically:
import { supyagent } from '@supyagent/sdk';
const client = supyagent({ apiKey: process.env.SUPYAGENT_API_KEY! });
const userClient = client.asAccount('user-123');
// Fetch all tools scoped to this user's integrations
const tools = await userClient.tools({ cache: 300 });
// Or use skills for a more token-efficient approach
const { systemPrompt, tools: skillTools } = await userClient.skills({ cache: 300 });See the SDK Partner Guide for full end-to-end examples.
Gmail — List Messages
curl https://app.supyagent.com/api/v1/google/gmail/messages \
-H "Authorization: Bearer sk_live_your_key_here" \
-H "X-Account-Id: user-123"const messages = await client.providerGet(
"/google/gmail/messages",
"user-123"
);messages = client.provider_get("/google/gmail/messages", "user-123")Gmail — Send Email
curl -X POST https://app.supyagent.com/api/v1/google/gmail/messages/send \
-H "Authorization: Bearer sk_live_your_key_here" \
-H "X-Account-Id: user-123" \
-H "Content-Type: application/json" \
-d '{
"to": "recipient@example.com",
"subject": "Hello from Supyagent",
"body": "This email was sent via the Connected Accounts API."
}'const result = await client.providerPost(
"/google/gmail/messages/send",
"user-123",
{
to: "recipient@example.com",
subject: "Hello from Supyagent",
body: "This email was sent via the Connected Accounts API.",
}
);result = client.provider_post(
"/google/gmail/messages/send",
"user-123",
{
"to": "recipient@example.com",
"subject": "Hello from Supyagent",
"body": "This email was sent via the Connected Accounts API.",
},
)Slack — Send Message
curl -X POST https://app.supyagent.com/api/v1/slack/messages \
-H "Authorization: Bearer sk_live_your_key_here" \
-H "X-Account-Id: user-123" \
-H "Content-Type: application/json" \
-d '{ "channel": "general", "text": "Hello from Supyagent!" }'const result = await client.providerPost(
"/slack/messages",
"user-123",
{ channel: "general", text: "Hello from Supyagent!" }
);result = client.provider_post(
"/slack/messages",
"user-123",
{"channel": "general", "text": "Hello from Supyagent!"},
)End-to-End Examples
Next.js API Route
A complete Next.js App Router API route that connects a user's Google account:
import { NextRequest, NextResponse } from "next/server";
const SUPYAGENT_API_KEY = process.env.SUPYAGENT_API_KEY!;
const BASE_URL = "https://app.supyagent.com/api/v1";
export async function POST(request: NextRequest) {
const { userId, provider } = await request.json();
// 1. Create or look up the connected account
const accountRes = await fetch(`${BASE_URL}/accounts`, {
method: "POST",
headers: {
"Authorization": `Bearer ${SUPYAGENT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
external_id: userId,
display_name: userId,
}),
});
const accountData = await accountRes.json();
// Handle duplicate — account already exists
const accountId = accountRes.status === 409
? (await fetch(`${BASE_URL}/accounts?limit=1&offset=0`, {
headers: { "Authorization": `Bearer ${SUPYAGENT_API_KEY}` },
}).then(r => r.json())).data.accounts.find(
(a: { external_id: string }) => a.external_id === userId
)?.id
: accountData.data.id;
// 2. Create a connect session
const connectRes = await fetch(`${BASE_URL}/accounts/${accountId}/connect`, {
method: "POST",
headers: {
"Authorization": `Bearer ${SUPYAGENT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
provider,
redirect_url: `${process.env.NEXT_PUBLIC_APP_URL}/integrations/callback`,
}),
});
const { data } = await connectRes.json();
return NextResponse.json({ connect_url: data.connect_url });
}Express Server
import express from "express";
const app = express();
app.use(express.json());
const SUPYAGENT_API_KEY = process.env.SUPYAGENT_API_KEY!;
const BASE_URL = "https://app.supyagent.com/api/v1";
// Proxy provider calls through your server
app.get("/api/gmail/messages", async (req, res) => {
const userId = req.headers["x-user-id"] as string; // Your auth
const response = await fetch(`${BASE_URL}/google/gmail/messages`, {
headers: {
"Authorization": `Bearer ${SUPYAGENT_API_KEY}`,
"X-Account-Id": userId,
},
});
const data = await response.json();
res.json(data);
});
app.listen(3000);Python Flask
import os
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
SUPYAGENT_API_KEY = os.environ["SUPYAGENT_API_KEY"]
BASE_URL = "https://app.supyagent.com/api/v1"
@app.route("/api/gmail/messages")
def gmail_messages():
user_id = request.headers.get("X-User-Id") # Your auth
response = requests.get(
f"{BASE_URL}/google/gmail/messages",
headers={
"Authorization": f"Bearer {SUPYAGENT_API_KEY}",
"X-Account-Id": user_id,
},
)
return jsonify(response.json())
if __name__ == "__main__":
app.run(port=3000)