# Custom Auth Configs (/docs/auth-configuration/custom-auth-configs)

> If you're building an agent, we recommend using [sessions](/docs/configuring-sessions) instead. See [Using custom auth configs](/docs/using-custom-auth-configuration) for how to use custom credentials with sessions.

Many toolkits support a level of customization for the auth config, specifically OAuth applications.

This guide will walk you through the process of customizing the auth config for toolkits where you can configure your own developer app.

# Creating a custom auth config

To create a custom auth config, click **Create Auth Config** in your dashboard, then navigate to **Authentication management** → **Manage authentication with custom credentials**.

You'll need to customize the auth config when you want to use different values than the defaults - such as your own subdomain, base URL, client ID, client secret, etc.

**Example: PostHog:**

You may change the subdomain for the PostHog toolkit to match your own instance.

![PostHog Auth Config Settings](/images/custom-auth-posthog.png)
*PostHog Auth Config Settings*

**Example: Hubspot:**

For Hubspot you may customize everything here. For each auth scheme there is a different set of fields.

If you choose to use your own developer app for the OAuth2 scheme, you will have to provide the client ID and client secret.

![Hubspot Auth Config Settings](/images/custom-auth-hubspot.png)
*Hubspot Auth Config Settings*

Toolkits that support OAuth2 allow using your own developer app. This is the recommended approach for most cases.

> **Use your own developer app!**: We recommend using your own developer app for the OAuth2 scheme as it is more suited for production usage with many users and more granular control over scopes.

However, getting OAuth approvals takes time, so Composio provides a default developer app!

# OAuth2 Auth Configs

#### Generate the OAuth Client ID and Client Secret

To set up a custom OAuth config, you'll need the OAuth Client ID and Client Secret.

You can generate the client ID and client secret from your provider's OAuth configuration page.

Examples for Google and GitHub:

**Google:**

![Google OAuth Configuration](/images/google-oauth-config.png)
*Google OAuth Configuration*

**GitHub:**

![GitHub OAuth Configuration](/images/github-oauth-config.png)
*GitHub OAuth Configuration*

#### Set the Authorized Redirect URI

When creating your OAuth app, make sure to configure the Authorized Redirect URI to point to the Composio callback URL below:

```
https://backend.composio.dev/api/v3/toolkits/auth/callback
```

#### Create the auth config

Once you have the OAuth credentials, you can add them to the auth config in the dashboard.

    1. Select the OAuth2 scheme.
    2. Select the scopes to request from users. Default scopes are pre-filled for most apps.
    3. Add the OAuth client ID and client secret for your developer app. Keep the redirect URL as is for now!
    4. Click Create!

![Auth Config Settings](/images/integration-step-3-0.png)
*Auth Config Settings*

This auth config is now ready to be used in your application!

**Python:**

```python
# Create a new connected account
connection_request = composio.connected_accounts.initiate(
    user_id="user_id",
    auth_config_id="ac_1234",
)
print(connection_request)

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

**TypeScript:**

```typescript
import { Composio } from '@composio/core';
const composio = new Composio({ apiKey: 'your_api_key' });
const userId = 'user_123';
const connReq = await composio.connectedAccounts.initiate(userId, "ac_1234");

console.log(connReq.redirectUrl);

const connection = await composio.connectedAccounts.waitForConnection(
  connReq.id
);

console.log(connection);
```

## White-labeling the OAuth Consent Screen

By default the users will see an OAuth screen like the one below:

![Composio's Domain in OAuth Consent Screen](/images/oauth-branding.png)
*Composio's Domain in OAuth Consent Screen*

The OAuth redirect URL is surfaced in some OAuth providers' consent screens. This may cause confusion for some users as that URL is not of the same domain as the application.

To remediate this:

#### Set the Authorized Redirect URI

Specify the Authorized Redirect URI to your own domain in the OAuth configuration.
For example:

```
https://yourdomain.com/api/composio-redirect
```

#### Create a redirect logic

Create a redirect logic, either through your DNS or in your application to redirect that endpoint to `https://backend.composio.dev/api/v3/toolkits/auth/callback`

**Example: API Route for OAuth Redirect**

**Python:**

```python
from fastapi import FastAPI
from fastapi.responses import RedirectResponse

from composio import Composio

# Create a FastAPI app
app = FastAPI()

# Create a Composio client
composio = Composio()

@app.get("/authorize/{toolkit}")
def authorize_app(toolkit: str):
    # retrieve the user id from your app
    user_id = "<user_id>"

    # retrieve the auth config id from your app
    auth_config_id = "<auth_config_id>"

    # initiate the connection request
    connection_request = composio.connected_accounts.initiate(
        user_id=user_id,
        auth_config_id=auth_config_id,
    )
    return RedirectResponse(url=connection_request.redirect_url)
```

**TypeScript:**

```typescript
import type { NextApiRequest, NextApiResponse } from 'next';

export default function handler(req: NextApiRequest, res: NextApiResponse) {
  // The target Composio endpoint that handles OAuth callbacks
  const composioEndpoint = 'https://backend.composio.dev/api/v3/toolkits/auth/callback';

  // Extract and preserve all query parameters
  const queryParams = new URLSearchParams();
  Object.entries(req.query).forEach(([key, value]) => {
    if (typeof value === 'string') {
      queryParams.append(key, value);

  });

  // Redirect to Composio with all query parameters intact
  const redirectUrl = `${composioEndpoint}?${queryParams.toString()}`;
  res.redirect(302, redirectUrl);

```

#### Create the auth config

Specify your custom redirect URI in the auth config settings!

![Auth Config Settings](/images/custom-redirect-uri.png)
*Auth Config Settings*

With this setup, you can use `https://yourdomain.com/api/composio-redirect` as your OAuth redirect URI, which will create a better user experience by keeping users on your domain during the OAuth flow.

**How does this work?**

The custom OAuth config allows you to use your own domain in the OAuth consent screen instead of Composio's domain. Here's the core difference:

backend.composio.dev]
C -->|Custom Domain| E[Provider redirects to<br/>yourdomain.com/api/composio-redirect]

E --> F[Your endpoint forwards to<br/>backend.composio.dev]

D --> G[Composio exchanges code for token]
F --> G

G --> H[Connection established]

style E fill:#e1f5fe
style F fill:#e1f5fe
style C fill:#fff3e0"
/>

**Key Benefits:**

    * **Custom Domain**: Users see your domain in OAuth consent screens, not Composio's
    * **Same Security**: Your domain just forwards the OAuth callback - no token handling
    * **Better UX**: Maintains brand consistency throughout the auth flow

The custom redirect endpoint is a simple passthrough that preserves all OAuth parameters while keeping users on your domain.

---

📚 **More documentation:** [View all docs](https://docs.composio.dev/llms.txt) | [Cookbooks](https://docs.composio.dev/llms.mdx/cookbooks) | [API Reference](https://docs.composio.dev/llms.mdx/reference)

---

# Composio SDK — Instructions for AI Code Generators

**Context:** This page documents the **direct tool execution API**. For most applications, the session-based pattern (`composio.create(user_id)` + `session.tools()`) is simpler — but if the user is here, they likely want direct execution.

---

## Key Patterns

### Authenticating Users

Create an **Auth Config** on [platform.composio.dev](https://platform.composio.dev), then use the auth config ID to generate a hosted auth URL:

```python
from composio import Composio

composio = Composio()
connection = composio.connected_accounts.link(
    user_id="user_123",
    auth_config_id="ac_...",  # from platform dashboard
)
print(connection.redirect_url)  # send user here to authenticate
```

```typescript
import { Composio } from "@composio/core";

const composio = new Composio();
const connection = await composio.connectedAccounts.link("user_123", "ac_...", {
    callbackUrl: "https://your-app.com/callback",
});
console.log(connection.redirectUrl); // send user here to authenticate
```

### Executing Tools

```python
tools = composio.tools.get("user_123", tools=["GITHUB_CREATE_ISSUE"])

result = composio.tools.execute(
    "GITHUB_CREATE_ISSUE",
    {"owner": "org", "repo": "repo", "title": "Bug report"},
    user_id="user_123",
)
```

```typescript
const tools = await composio.tools.get("user_123", { tools: ["GITHUB_CREATE_ISSUE"] });

const result = await composio.tools.execute("GITHUB_CREATE_ISSUE", {
    userId: "user_123",
    arguments: { owner: "org", repo: "repo", title: "Bug report" },
});
```

---

## Rules

1. **`user_id` is required** — pass it to `tools.get()`, `tools.execute()`, and `provider.handle_tool_calls()`.
2. **`tools.execute()` signature** — Python: `execute(slug, arguments_dict, *, user_id=...)` (arguments is the second positional param). TypeScript: `execute(slug, { userId, arguments })`.
3. **Provider at init** — `Composio(provider=OpenAIProvider())` in Python, `new Composio({ provider: new OpenAIProvider() })` in TypeScript. Defaults to OpenAI if omitted.
4. **Correct provider imports** — `composio_<provider>` for Python, `@composio/<provider>` for TypeScript. For OpenAI Agents SDK use `composio_openai_agents` / `@composio/openai-agents`.
