Skip to main content

Authenticating Tools

Create auth configs and connect user accounts

The first step in authenticating your users is to create an Auth Config. Every toolkit has its own authentication method such as OAuth, API key, Basic Auth, or custom schemes.

An Auth Config is a blueprint that defines how authentication works for a toolkit across all your users. It defines:

  1. Authentication method - OAuth2, Bearer token, API key, or Basic Auth
  2. Scopes - what actions your tools can perform
  3. Credentials - whether you'll use your own app credentials or Composio's managed auth

Creating an auth config

Using the Dashboard

Selecting a toolkit

Navigate to Auth Configs tab in your dashboard and click "Create Auth Config". Find and select the toolkit you want to integrate (e.g., Gmail, Slack, GitHub).

Selecting the Authentication method

Each toolkit supports different authentication methods such as OAuth, API Key, Bearer Token. Select from the available options for your toolkit.

Configure scopes

Depending on your authentication method, you may need to configure scopes:

  • OAuth2: Configure scopes for what data and actions your integration can access.
  • API Key/Bearer Token: Permissions are typically fixed based on the key's access level.

Authentication Management

For OAuth toolkits:

  • Development/Testing: Use Composio's managed authentication (no setup required)
  • Production: Generate your own OAuth credentials from the toolkit's developer portal

For custom authentication schemes:

You must provide your own credentials regardless of environment.

Want to remove Composio branding from OAuth screens? See Custom Auth Configs for white-labeling options.

You are all set!

Click "Create Auth Configuration" button and you have completed your first step! Now you can move ahead to authenticating your users by Connecting an Account.

Auth configs are reusable

Auth configs contain your developer credentials and app-level settings (scopes, authentication method, etc.). Once created, you can reuse the same auth config for all your users.

When to create multiple auth configs?

You should create multiple auth configs for the same toolkit when you need:

  • Different authentication methods - One OAuth config and one API key config
  • Different scopes - Separate configs for read-only vs full access
  • Different OAuth apps - Using separate client credentials for different environments
  • Different permission levels - Limiting actions for specific use cases

Connecting an account

With an auth config created, you're ready to authenticate your users!

You can either use Connect Link for a hosted authentication flow, or use Direct SDK Integration.

User authentication requires a User ID - a unique identifier that groups connected accounts together. Learn more about User Management to understand how to structure User IDs for your application.

Choose the section below that matches your toolkit's authentication method:

Redirect users to a Composio-hosted URL that handles the entire authentication process—OAuth flows, API key collection, or custom fields like subdomain. You can specify a callback URL to control where users return after authentication.

Connect Link authentication screen
Connect Link authentication screen
from composio import Composio

composio = Composio(api_key="your_api_key")

# Use the "AUTH CONFIG ID" from your dashboard
auth_config_id = "your_auth_config_id"

# Use a unique identifier for each user in your application
user_id = 'user-1349-129-12'

connection_request = composio.connected_accounts.link(
    user_id=user_id,
    auth_config_id=auth_config_id,
    callback_url='https://your-app.com/callback'
)

redirect_url = connection_request.redirect_url
print(f"Visit: {redirect_url} to authenticate your account")
import { Composio } from '@composio/core';

const composio = new Composio({apiKey: "your_api_key"});

// Use the "AUTH CONFIG ID" from your dashboard
const authConfigId = 'your_auth_config_id';

// Use a unique identifier for each user in your application
const userId = 'user-1349-129-12';

const connectionRequest = await composio.connectedAccounts.link(userId, authConfigId, {
  callbackUrl: 'https://your-app.com/callback'
});
const redirectUrl = connectionRequest.redirectUrl;
console.log(`Visit: ${redirectUrl} to authenticate your account`);

By default, users will see a Composio-branded authentication experience when connecting their accounts. To customize this interface with your application's branding:

  1. Navigate to your Project Settings and select Auth Screen
  2. Configure your Logo and App Title

These settings will apply to all authentication flows using Connect Link, providing a white-labeled experience that maintains your brand identity throughout the authentication process.

For complete white-labeling including OAuth consent screens (removing Composio's domain), see Custom Auth Configs - White-labeling.

Direct SDK Integration

Choose the section below that matches your toolkit's authentication method:

OAuth Connections

For OAuth flows, you'll redirect users to complete authorization. You can specify a callback URL to control where users return after authentication:

from composio import Composio

composio = Composio(api_key="YOUR_COMPOSIO_API_KEY")

# Use the "AUTH CONFIG ID" from your dashboard
auth_config_id = "your_auth_config_id"

# Use a unique identifier for each user in your application
user_id = "user-1349-129-12"

connection_request = composio.connected_accounts.initiate(
  user_id=user_id,
  auth_config_id=auth_config_id,
  config={"auth_scheme": "OAUTH2"},
  callback_url="https://www.yourapp.com/callback"
)
print(f"Redirect URL: {connection_request.redirect_url}")

connected_account = connection_request.wait_for_connection()

# Alternative: if you only have the connection request ID
# connected_account = composio.connected_accounts.wait_for_connection(
#  connection_request.id)
# Recommended when the connection_request object is no longer available

print(f"Connection established: {connected_account.id}")
import { Composio } from '@composio/core';

const composio = new Composio({apiKey: "YOUR_COMPOSIO_API_KEY"});

// Use the "AUTH CONFIG ID" from your dashboard
const authConfigId = 'your_auth_config_id';
// Use a unique identifier for each user in your application
const userId = 'user_4567';

const connRequest = await composio.connectedAccounts.initiate(
  userId,
  authConfigId,
  {
    callbackUrl: 'https://www.yourapp.com/callback',
  }
);
console.log(`Redirect URL: ${connRequest.redirectUrl}`);

const connectedAccount = await connRequest.waitForConnection();

// Alternative: if you only have the connection request ID
// const connectedAccount = await composio.connectedAccounts
//   .waitForConnection(connRequest.id);
// Recommended when the connRequest object is no longer available

console.log(`Connection established: ${connectedAccount.id}`);

Services with Additional Parameters

Some services like Zendesk require additional parameters such as subdomain:

# For Zendesk - include subdomain
connection_request = composio.connected_accounts.initiate(
  user_id=user_id,
  auth_config_id=auth_config_id,
  config=auth_scheme.oauth2(subdomain="mycompany")  # For mycompany.zendesk.com
)
import { AuthScheme } from '@composio/core';
// For Zendesk - include subdomain
const connRequest = await composio.connectedAccounts.initiate(userId, authConfigId, {
  config: AuthScheme.OAuth2({
    subdomain: 'mycompany',
  }),
});

API Key Connections

For API key authentication, you can either collect API keys from each user or use your own API key for all users. Popular toolkits that use API keys include Stripe, Perplexity, etc.

Here is how to initiate the flow:

from composio import Composio

composio = Composio(api_key="your_api_key")

# Use the "AUTH CONFIG ID" from your dashboard
auth_config_id = "your_auth_config_id"

# Use a unique identifier for each user in your application
user_id = "user_12323"

# API key provided by the user (collected from your app's UI)
# or use your own key
user_api_key = "user_api_key_here"

connection_request = composio.connected_accounts.initiate(
  user_id=user_id,
  auth_config_id=auth_config_id,
  config={
    "auth_scheme": "API_KEY", "val": {"api_key": user_api_key}
  }
)

print(f"Connection established: {connection_request.id}")
import { Composio, AuthScheme } from '@composio/core';

const composio = new Composio({ apiKey: 'your_api_key' });

// Use the "AUTH CONFIG ID" from your dashboard
const authConfigId = 'your_auth_config_id';
// Use a unique identifier for each user in your application
const userId = 'user12345678';
// API key provided by the user (collected from your app's UI)
const userApiKey = 'user_api_key_here';

const connectionRequest = await composio.connectedAccounts.initiate(userId, authConfigId, {
  config: AuthScheme.APIKey({
    api_key: userApiKey,
  }),
});

console.log(`Connection established: ${connectionRequest.id}`);

Fetching the required config parameters for an Auth Config

When working with any toolkit, you can inspect an auth config to understand its authentication requirements and expected parameters.

Here is how you would fetch the authentication method and input fields:

from composio import Composio

composio = Composio(api_key="your_api_key")

# Use the "AUTH CONFIG ID" from your dashboard
auth_config_id = "your_auth_config_id"

# Fetch the auth configuration details
auth_config = composio.auth_configs.get(auth_config_id)

# Check what authentication method this config uses
print(f"Authentication method: {auth_config.auth_scheme}")

# See what input fields are required
print(f"Required fields: {auth_config.expected_input_fields}")
import { Composio } from '@composio/core';

const composio = new Composio({ apiKey: 'your_api_key' });

// Use the "AUTH CONFIG ID" from your dashboard
const authConfigId = 'your_auth_config_id';

// Fetch the auth configuration details
const authConfig = await composio.authConfigs.get(authConfigId);

console.log(`Authentication method: ${authConfig.authScheme}`);
console.log(`Required fields:`, authConfig.expectedInputFields);

Other Authentication Methods

Composio also supports a wide range of other auth schemas:

Bearer Token - Similar to API keys, provide the user's bearer token directly when creating the connection.

Basic Auth - Provide username and password credentials for services that use HTTP Basic Authentication.

Custom Schemes - Some toolkits use their own custom authentication methods. Follow the toolkit-specific requirements for such cases.

Fetching auth config

For any of these methods, fetch the config parameter to determine the exact fields required. Every toolkit has its own requirements, and understanding these is essential for successfully creating connections.

Learn how to Manage connected accounts after users authenticate.

Connection Statuses

After creating a connection, it will have one of the following statuses that indicates its current state:

StatusDescription
ACTIVEConnection is established and working. You can execute tools with this connection.
INACTIVEConnection is temporarily disabled. Re-enable it to use the connection again.
PENDINGConnection is being processed. Wait for it to become active.
INITIATEDConnection request has started but not yet completed. User may still need to complete authentication.
EXPIREDConnection credentials have expired. Composio automatically attempts to refresh credentials before marking as expired. Re-authenticate to restore access.
FAILEDConnection attempt failed. Check error details and try creating a new connection.

When credentials expire for OAuth connections, Composio automatically attempts to refresh them using the refresh token. The connection is only marked as EXPIRED after multiple refresh attempts have failed.

Waiting for Connection Establishment

The waitForConnection method allows you to poll for a connection to become active after initiating authentication. This is useful when you need to ensure a connection is ready before proceeding.

# Wait for the connection to be established
connected_account = connection_request.wait_for_connection()
print(connected_account.id)

# Alternative: Wait with custom timeout
# connected_account = connection_request.wait_for_connection(120)  # 2 minute timeout

# Alternative: If you only have the connection request ID (e.g., stored in database)
# connection_id = connection_request.id  # You can store this ID in your database
# connected_account = composio.connected_accounts.wait_for_connection(connection_id, 60)
// Wait for the connection to be established
const connectedAccount = await connectionRequest.waitForConnection();
console.log(connectedAccount.id);

// Alternative: Wait with custom timeout
// const connectedAccount = await connectionRequest.waitForConnection(120000);  // 2 minutes

// Alternative: If you only have the connection request ID (e.g., stored in database)
// const connectionId = connectionRequest.id;  // You can store this ID in your database
// const connectedAccount = await composio.connectedAccounts.waitForConnection(connectionId, 60000);

The method continuously polls the Composio API until the connection:

  • Becomes ACTIVE (returns the connected account)
  • Enters a terminal state like FAILED or EXPIRED (throws an error)
  • Exceeds the specified timeout (throws a timeout error)

Checking Connection Status

You can check the status of a connected account programmatically:

# Get a specific connected account
connected_account = composio.connected_accounts.get("your_connected_account_id")
print(f"Status: {connected_account.status}")

# Filter connections by user_id, auth_config_id, and status (only active accounts)
filtered_connections = composio.connected_accounts.list(
    user_ids=["user_123"],
    auth_config_ids=["your_auth_config_id"],
    statuses=["ACTIVE"]
)
for connection in filtered_connections.items:
    print(f"{connection.id}: {connection.status}")
// Get a specific connected account by its nanoid
const connectedAccount = await composio.connectedAccounts.get('your_connected_account_id');
console.log(`Status: ${connectedAccount.status}`);

// Filter connections by user_id, auth_config_id, and status (only active accounts)
const filteredConnections = await composio.connectedAccounts.list({
  userIds: ['user_123'],
  authConfigIds: ['your_auth_config_id'],
  statuses: ['ACTIVE']
});
filteredConnections.items.forEach(connection => {
  console.log(`${connection.id}: ${connection.status}`);
});

Only connections with ACTIVE status can be used to execute tools. If a connection is in any other state, you'll need to take appropriate action (re-authenticate, wait for processing, etc.) before using it.

Next Step

With authentication set up, you can now fetch and execute tools. See Executing Tools to get started.