Supyagent
Connected Accounts

Quickstart

Register as a partner, create your first connected account, and connect an OAuth provider in under 5 minutes.

Quickstart

This guide walks you through the full flow: registering as a partner, creating a connected account for one of your users, and connecting their first OAuth integration.

Prerequisites

  • A Supyagent account at supyagent.com
  • An application where you want to offer third-party integrations to your users

1. Register as a Partner

Go to Settings > Partner in the Supyagent dashboard, or navigate directly to supyagent.com/settings/partner.

Fill in your company details:

FieldRequiredDescription
Company NameYesYour company or product name (max 255 chars)
WebsiteYesYour company URL
Contact EmailNoTeam contact email
Use CaseNoBrief description of how you'll use the API (max 1000 chars)

On registration, you receive:

  • Partner ID — your unique identifier
  • API Key — starts with sk_live_. Save it immediately — it's only shown once

2. Create a Connected Account

Use the API key to create a connected account for one of your users:

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 response = await fetch("https://app.supyagent.com/api/v1/accounts", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_live_your_key_here",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    external_id: "user-123",
    display_name: "Jane Smith",
    metadata: { plan: "pro", company: "Acme Corp" },
  }),
});

const { ok, data } = await response.json();
console.log(data.id); // Supyagent account UUID
import requests

response = requests.post(
    "https://app.supyagent.com/api/v1/accounts",
    headers={
        "Authorization": "Bearer sk_live_your_key_here",
        "Content-Type": "application/json",
    },
    json={
        "external_id": "user-123",
        "display_name": "Jane Smith",
        "metadata": {"plan": "pro", "company": "Acme Corp"},
    },
)

data = response.json()
print(data["data"]["id"])  # Supyagent account UUID

Response:

{
  "ok": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "external_id": "user-123",
    "display_name": "Jane Smith",
    "metadata": { "plan": "pro", "company": "Acme Corp" },
    "created_at": "2026-02-25T10:00:00.000Z"
  }
}

The id in the response is the Supyagent account ID. The external_id is your internal identifier — use it to map between your system and Supyagent.

3. Initiate an OAuth Flow

Start a connect session to let the user authorize a provider. You specify the provider and a redirect_url where the user returns after authorizing:

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/integrations/callback"
  }'
const accountId = "550e8400-e29b-41d4-a716-446655440000";

const response = await fetch(
  `https://app.supyagent.com/api/v1/accounts/${accountId}/connect`,
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer sk_live_your_key_here",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      provider: "google",
      redirect_url: "https://yourapp.com/integrations/callback",
    }),
  }
);

const { data } = await response.json();
// Redirect user to data.connect_url
account_id = "550e8400-e29b-41d4-a716-446655440000"

response = requests.post(
    f"https://app.supyagent.com/api/v1/accounts/{account_id}/connect",
    headers={
        "Authorization": "Bearer sk_live_your_key_here",
        "Content-Type": "application/json",
    },
    json={
        "provider": "google",
        "redirect_url": "https://yourapp.com/integrations/callback",
    },
)

data = response.json()["data"]
# Redirect user to data["connect_url"]

Response:

{
  "ok": true,
  "data": {
    "connect_url": "https://accounts.google.com/o/oauth2/v2/auth?client_id=...&state=...&code_challenge=...",
    "session_id": "660e8400-e29b-41d4-a716-446655440001",
    "expires_at": "2026-02-25T10:30:00.000Z"
  }
}

4. Redirect the User

Open the connect_url in the user's browser. This can be a redirect, a popup, or an embedded iframe — whatever fits your app:

<a href="https://accounts.google.com/o/oauth2/v2/auth?...">
  Connect Google Account
</a>

The user sees the standard OAuth consent screen from the provider (e.g., Google). After they authorize, the provider redirects to Supyagent's callback handler, which:

  1. Exchanges the authorization code for access and refresh tokens
  2. Encrypts and stores the tokens
  3. Auto-enables available services (Gmail, Calendar, Drive, etc.)
  4. Redirects the user back to your redirect_url

5. Handle the Callback

The user lands back on your redirect_url with query parameters:

On success:

https://yourapp.com/integrations/callback?status=success&provider=google&account_id=user-123

On failure:

https://yourapp.com/integrations/callback?error=access_denied
ParameterDescription
statussuccess when OAuth completed successfully
providerThe provider that was connected (e.g., google)
account_idThe connected account's external_id
errorError code if something went wrong

Possible error values:

ErrorMeaning
access_deniedUser denied the OAuth permission request
session_expiredThe connect session exceeded its 30-minute window
session_already_usedThis session was already completed
no_codeOAuth provider didn't return an authorization code
token_exchange_failedFailed to exchange the code for tokens

6. Make API Calls

Once a provider is connected, make API calls on behalf of the connected account by passing the X-Account-Id header with the account's external_id:

The X-Account-Id header takes the account's external_id (your internal user identifier), not the Supyagent UUID.

# List Gmail messages for the connected account
curl https://app.supyagent.com/api/v1/google/gmail/messages \
  -H "Authorization: Bearer sk_live_your_key_here" \
  -H "X-Account-Id: user-123"
# Send a Slack message on behalf of the connected account
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 the API!"
  }'
// List Gmail messages for the connected account
const messages = await fetch(
  "https://app.supyagent.com/api/v1/google/gmail/messages",
  {
    headers: {
      "Authorization": "Bearer sk_live_your_key_here",
      "X-Account-Id": "user-123",
    },
  }
);

// Send a Slack message on behalf of the connected account
const slack = await fetch(
  "https://app.supyagent.com/api/v1/slack/messages",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer sk_live_your_key_here",
      "X-Account-Id": "user-123",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      channel: "general",
      text: "Hello from the API!",
    }),
  }
);
# List Gmail messages for the connected account
messages = requests.get(
    "https://app.supyagent.com/api/v1/google/gmail/messages",
    headers={
        "Authorization": "Bearer sk_live_your_key_here",
        "X-Account-Id": "user-123",
    },
)

# Send a Slack message on behalf of the connected account
slack = requests.post(
    "https://app.supyagent.com/api/v1/slack/messages",
    headers={
        "Authorization": "Bearer sk_live_your_key_here",
        "X-Account-Id": "user-123",
        "Content-Type": "application/json",
    },
    json={
        "channel": "general",
        "text": "Hello from the API!",
    },
)

Supyagent handles token decryption, automatic refresh, and provider API calls transparently.

7. Poll Session Status (Optional)

If you need to check on a connect session programmatically (e.g., for a polling-based UX instead of redirect-based), use the session status endpoint:

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 accountId = "550e8400-e29b-41d4-a716-446655440000";
const sessionId = "660e8400-e29b-41d4-a716-446655440001";

const response = await fetch(
  `https://app.supyagent.com/api/v1/accounts/${accountId}/connect/${sessionId}`,
  {
    headers: {
      "Authorization": "Bearer sk_live_your_key_here",
    },
  }
);

const { data } = await response.json();
console.log(data.status); // "pending" | "completed" | "expired" | "failed"
account_id = "550e8400-e29b-41d4-a716-446655440000"
session_id = "660e8400-e29b-41d4-a716-446655440001"

response = requests.get(
    f"https://app.supyagent.com/api/v1/accounts/{account_id}/connect/{session_id}",
    headers={"Authorization": "Bearer sk_live_your_key_here"},
)

data = response.json()["data"]
print(data["status"])  # "pending" | "completed" | "expired" | "failed"
{
  "ok": true,
  "data": {
    "session_id": "660e8400-e29b-41d4-a716-446655440001",
    "provider": "google",
    "status": "completed",
    "created_at": "2026-02-25T10:00:00.000Z",
    "expires_at": "2026-02-25T10:30:00.000Z"
  }
}

What's Next