Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ComposioHQ/composio/llms.txt

Use this file to discover all available pages before exploring further.

A connected account is created when a user authenticates with a toolkit. It stores their credentials — OAuth tokens or API keys — and links them to the user ID you provide. Composio handles token refresh automatically, so you never need to manage expiration or re-authentication logic yourself. Connected accounts persist across sessions, meaning a user who connected GitHub last week can pick up a new conversation today without re-authenticating.

Listing connected accounts

Retrieve connected accounts for a user, a toolkit, or both:
import { Composio } from '@composio/core';

const composio = new Composio({ apiKey: process.env.COMPOSIO_API_KEY });

// All connected accounts for a user
const { items } = await composio.connectedAccounts.list({
  userIds: ["user_123"],
});

items.forEach((account) => {
  console.log(account.id);             // "ca_abc123"
  console.log(account.toolkit.slug);   // "github"
  console.log(account.status);         // "ACTIVE"
});

// Filter by toolkit
const githubAccounts = await composio.connectedAccounts.list({
  userIds: ["user_123"],
  toolkitSlugs: ["github"],
});

// Filter by status
const activeAccounts = await composio.connectedAccounts.list({
  userIds: ["user_123"],
  statuses: ["ACTIVE"],
});

Getting a specific account

Fetch the full details of a single connected account by its ID:
const account = await composio.connectedAccounts.get("ca_abc123");

console.log(account.status);       // "ACTIVE"
console.log(account.toolkit.slug); // "github"
console.log(account.userId);       // "user_123"

Creating a connection

To connect a user to a toolkit, initiate a connection using connectedAccounts.link(). This returns a ConnectionRequest that includes a redirectUrl — send the user there to complete OAuth or enter their API key.
connectedAccounts.link() is the recommended method for OAuth-based toolkits. It works with both Composio-managed and custom auth configs.
import { Composio } from '@composio/core';

const composio = new Composio({ apiKey: process.env.COMPOSIO_API_KEY });

const connectionRequest = await composio.connectedAccounts.link(
  "user_123",
  "ac_gmail_oauth2", // your auth config ID
  {
    callbackUrl: "https://myapp.com/auth/callback",
  }
);

console.log(connectionRequest.redirectUrl);
// "https://connect.composio.dev/link/ln_abc123"

// Redirect the user to this URL in your app
For API-key-based toolkits, use connectedAccounts.initiate() and pass the key directly in the connection state — no redirect required:
import { AuthScheme } from '@composio/core';

const connectionRequest = await composio.connectedAccounts.initiate(
  "user_123",
  "ac_linear_apikey",
  {
    config: AuthScheme.ApiKey({ api_key: "lin_api_your_key_here" }),
  }
);

Waiting for connection

After redirecting a user for OAuth, poll until the connection becomes active using waitForConnection():
const connectionRequest = await composio.connectedAccounts.link(
  "user_123",
  "ac_gmail_oauth2"
);

console.log(connectionRequest.redirectUrl);
// Redirect the user, then wait:

const connectedAccount = await connectionRequest.waitForConnection(60000); // 60s timeout
console.log(connectedAccount.status); // "ACTIVE"
console.log(connectedAccount.id);     // "ca_abc123"
You can also poll by connected account ID directly:
const account = await composio.connectedAccounts.waitForConnection(
  "ca_abc123",
  120000 // 2 minute timeout
);

Multiple accounts per toolkit

A user can connect multiple accounts for the same toolkit — for example, a work Gmail and a personal Gmail. By default, connectedAccounts.link() and connectedAccounts.initiate() raise an error if an active connection already exists for the same auth config and user. Pass allowMultiple: true to permit multiple connections:
// Connect a second Gmail account for the same user
const secondConnection = await composio.connectedAccounts.link(
  "user_123",
  "ac_gmail_oauth2",
  { allowMultiple: true }
);

// List both Gmail connections for this user
const gmailAccounts = await composio.connectedAccounts.list({
  userIds: ["user_123"],
  toolkitSlugs: ["gmail"],
});
console.log(gmailAccounts.items.length); // 2
When a session needs to use a specific account, pass the connected account ID via connectedAccounts in the session config:
const session = await composio.create("user_123", {
  connectedAccounts: {
    gmail: ["ca_work_gmail_id"],
  },
});

Connection status

A connected account’s status field reflects the current state of the credentials:
StatusMeaning
ACTIVECredentials are valid and the account can be used
INITIATEDThe OAuth flow has been started but not completed
FAILEDAuthentication failed or was rejected by the provider
EXPIREDThe credentials have expired and need to be refreshed
INACTIVEThe account has been manually disabled via the API
REVOKEDAccess was revoked by the user or the provider
Composio automatically refreshes OAuth tokens before they expire. A token expiry does not normally change the status to FAILED — you only see FAILED if the provider explicitly rejects the credentials. Use INACTIVE to temporarily disable an account without removing it.
You can enable or disable an account programmatically:
// Disable a connected account (sets status to INACTIVE)
await composio.connectedAccounts.disable("ca_abc123");

// Re-enable it later (restores to ACTIVE)
await composio.connectedAccounts.enable("ca_abc123");

Authentication

Auth configs, OAuth flows, and Connect Link generation

Sessions

Scoping connected accounts to a session

Authenticating Users

Step-by-step guide to onboarding users with Connect Links

CLI Overview

Manage connected accounts from the command line

Build docs developers (and LLMs) love