Importing existing connections
If your users have already authenticated with a service and you have their credentials (API keys, bearer tokens, etc.), you can pass those directly into Composio. No re-authentication required.
This is useful when:
- Your app already stores API keys or tokens for users
- You're adopting Composio and want to onboard existing users without disrupting them
- You want to use bearer tokens with OAuth toolkits (Gmail, GitHub, Slack, etc.) without setting up an OAuth app
How it works
Prerequisites
- An auth config for the toolkit you're importing into
- The existing credentials for each user (API keys, bearer tokens, username/password, etc.)
- A user ID for each user — any string that uniquely identifies them in your system
API keys
For services that use API key authentication (e.g., SendGrid, Tavily, PostHog):
from composio import Composio
from composio.types import auth_scheme
composio = Composio(api_key="your-api-key")
connection = composio.connected_accounts.initiate(
user_id="user_123",
auth_config_id="ac_your_auth_config",
config=auth_scheme.api_key({
"api_key": "sg-existing-sendgrid-key",
}),
)
# API key connections are immediately active
print(f"Connected: {connection.id}")import { Composio, AuthScheme } from '@composio/core';
const composio = new Composio({ apiKey: 'your-api-key' });
const connection = await composio.connectedAccounts.initiate(
'user_123',
'ac_your_auth_config',
{
config: AuthScheme.APIKey({
api_key: 'sg-existing-sendgrid-key',
}),
}
);
// API key connections are immediately active
console.log('Connected:', connection.id);Bearer tokens
If you already have an access token for a service (e.g., from an OAuth flow you manage), you can pass it directly to Composio as a bearer token. This works with all toolkits that support OAuth2 or S2S auth — Gmail, GitHub, Slack, Google Docs, and more. Any additional parameters the toolkit supports (e.g., subdomain, base_url) work the same way.
After creating an auth config with authScheme: "BEARER_TOKEN", use the snippet below to create a connected account. Since access tokens typically expire, use the PATCH endpoint to push a refreshed token whenever it changes on your end.
from composio import Composio
from composio.types import auth_scheme
composio = Composio(api_key="your-api-key")
connection = composio.connected_accounts.initiate(
user_id="user_123",
auth_config_id="ac_your_auth_config",
config=auth_scheme.bearer_token({
"token": "existing-bearer-token",
}),
)
# Bearer token connections are immediately active
print(f"Connected: {connection.id}")import { Composio, AuthScheme } from '@composio/core';
const composio = new Composio({ apiKey: 'your-api-key' });
const connection = await composio.connectedAccounts.initiate(
'user_123',
'ac_your_auth_config',
{
config: AuthScheme.BearerToken({
token: 'existing-bearer-token',
}),
}
);
// Bearer token connections are immediately active
console.log('Connected:', connection.id);Basic auth
from composio import Composio
from composio.types import auth_scheme
composio = Composio(api_key="your-api-key")
connection = composio.connected_accounts.initiate(
user_id="user_123",
auth_config_id="ac_your_auth_config",
config=auth_scheme.basic({
"username": "user@example.com",
"password": "existing-password",
}),
)
# Basic auth connections are immediately active
print(f"Connected: {connection.id}")import { Composio, AuthScheme } from '@composio/core';
const composio = new Composio({ apiKey: 'your-api-key' });
const connection = await composio.connectedAccounts.initiate(
'user_123',
'ac_your_auth_config',
{
config: AuthScheme.Basic({
username: 'user@example.com',
password: 'existing-password',
}),
}
);
// Basic auth connections are immediately active
console.log('Connected:', connection.id);Updating credentials
When credentials expire or rotate, update them in place without recreating the connection. Fields you omit are preserved. Fields set to null are removed.
composio.connected_accounts.update(
"ca_your_connection_id",
connection={
"state": {
"authScheme": "BEARER_TOKEN",
"val": {"token": "new-access-token"},
},
},
)await composio.connectedAccounts.update('ca_your_connection_id', {
connection: {
state: {
authScheme: 'BEARER_TOKEN',
val: { token: 'new-access-token' },
},
},
});curl -X PATCH https://backend.composio.dev/api/v3/connected_accounts/ca_xxx \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"connection":{"state":{"authScheme":"BEARER_TOKEN","val":{"token":"new-access-token"}}}}'composio.connected_accounts.update(
"ca_your_connection_id",
connection={
"state": {
"authScheme": "API_KEY",
"val": {"generic_api_key": "new-api-key"},
},
},
)await composio.connectedAccounts.update('ca_your_connection_id', {
connection: {
state: {
authScheme: 'API_KEY',
val: { generic_api_key: 'new-api-key' },
},
},
});curl -X PATCH https://backend.composio.dev/api/v3/connected_accounts/ca_xxx \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"connection":{"state":{"authScheme":"API_KEY","val":{"generic_api_key":"new-api-key"}}}}'composio.connected_accounts.update(
"ca_your_connection_id",
connection={
"state": {
"authScheme": "BASIC",
"val": {"username": "user@example.com", "password": "new-password"},
},
},
)await composio.connectedAccounts.update('ca_your_connection_id', {
connection: {
state: {
authScheme: 'BASIC',
val: { username: 'user@example.com', password: 'new-password' },
},
},
});curl -X PATCH https://backend.composio.dev/api/v3/connected_accounts/ca_xxx \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"connection":{"state":{"authScheme":"BASIC","val":{"username":"user@example.com","password":"new-password"}}}}'Using in your session
Pass the auth config or connection ID when creating a session:
session = composio.create(
"user_123",
auth_configs={"gmail": "ac_your_auth_config"},
toolkits=["gmail"],
)const session = await composio.create('user_123', {
authConfigs: { gmail: 'ac_your_auth_config' },
toolkits: ['gmail'],
});