# Create a link session for a toolkit in a tool router session

**Documentation:** /reference/api-reference/tool-router/postToolRouterSessionBySessionIdLink

Initiates an authentication link session for a specific toolkit within a tool router session. Returns a link token and redirect URL that users can use to complete the OAuth flow.

---

## POST `/api/v3.1/tool_router/session/{session_id}/link`

**Endpoint:** `https://backend.composio.dev/api/v3.1/tool_router/session/{session_id}/link`

**Summary:** Create a link session for a toolkit in a tool router session

Initiates an authentication link session for a specific toolkit within a tool router session. Returns a link token and redirect URL that users can use to complete the OAuth flow.

### Authentication

**ApiKeyAuth** - API Key in `header` header `x-api-key` OR **UserApiKeyAuth** - API Key in `header` header `x-user-api-key`

### Path Parameters

- `session_id` (string (toolRouterSessionId)) *(required)*: The unique identifier of the tool router session

### Request Body

**Schema:**

- `toolkit` (string) *(required)*: The unique slug identifier of the toolkit to connect
- `alias` (string): A human-readable alias for this connected account. Must be unique per entity and toolkit within the project.
- `callback_url` (string (uri)): URL where users will be redirected after completing auth
- `experimental` (object): Experimental features - not stable, may be modified or removed in future versions.
  - `account_type` (enum: "PRIVATE" | "SHARED"): Sharing model for this connected account. PRIVATE (default) is usable only by the owning user_id. SHARED is reachable from a tool-router session ONLY when explicitly pinned in the session config — at most one SHARED connection per toolkit per session. Sessions never use a SHARED connection implicitly.
  - `acl_config_for_shared` (object): Access control for SHARED connections. Resolution rule (only fires when caller != creator): user in not_allowed_user_ids → DENY; allow_all_users=true → ALLOW; user in allowed_user_ids → ALLOW; else DENY. Default state (omitted or {}) is deny-by-default — only the creator can use.
    - `allow_all_users` (boolean): Wildcard "any user_id in the project" allow toggle. Only valid on SHARED connections.
    - `allowed_user_ids` (array<string>): Explicit allow list of user_ids who can use this SHARED connection.
    - `not_allowed_user_ids` (array<string>): Explicit deny list. Wins on conflict with allow_all_users and allowed_user_ids.

**Example:**

```json
{
  "toolkit": "string",
  "alias": "string",
  "callback_url": "https://example.com",
  "experimental": {
    "account_type": "PRIVATE",
    "acl_config_for_shared": {
      "allow_all_users": true,
      "allowed_user_ids": [
        "..."
      ],
      "not_allowed_user_ids": [
        "..."
      ]
    }
  }
}
```

### Responses

#### 201 - Successfully created link session. Returns link token, redirect URL, and connected account ID.

**Response Schema:**

- `link_token` (string) *(required)*: Token used to complete the authentication flow
- `redirect_url` (string (uri)) *(required)*: The URL where users should be redirected to complete OAuth
- `connected_account_id` (string (connectedAccountId)) *(required)*: The unique identifier for the connected account
- `experimental` (object): Experimental features - not stable, may be modified or removed in future versions.
  - `account_type` (enum: "PRIVATE" | "SHARED") *(required)*: Sharing model for this connected account. PRIVATE is usable only by the owning user_id. SHARED is reachable from a tool-router session only when explicitly pinned in the session config.
  - `acl_config_for_shared` (object): Access control for SHARED connections. Visible only to the connection creator and project/org API key callers; non-creator cookie callers receive the response without this block.
    - `allow_all_users` (boolean) *(required)*
    - `allowed_user_ids` (array<string>) *(required)*
    - `not_allowed_user_ids` (array<string>) *(required)*

**Example Response:**

```json
{
  "link_token": "string",
  "redirect_url": "https://example.com",
  "connected_account_id": "string",
  "experimental": {
    "account_type": "PRIVATE",
    "acl_config_for_shared": {
      "allow_all_users": true,
      "allowed_user_ids": [
        "..."
      ],
      "not_allowed_user_ids": [
        "..."
      ]
    }
  }
}
```

#### 400 - Bad request. This may occur if the toolkit slug is invalid, request parameters are malformed, or a connected account is already defined for this toolkit in the session configuration.

**Response Schema:**

- `error` (object) *(required)*
  - `message` (string) *(required)*
  - `code` (number) *(required)*
  - `slug` (string) *(required)*
  - `status` (number) *(required)*
  - `request_id` (string)
  - `suggested_fix` (string)
  - `errors` (array<string>)

#### 401 - Unauthorized. Authentication is required or the provided credentials are invalid.

**Response Schema:**

- `error` (object) *(required)*
  - `message` (string) *(required)*
  - `code` (number) *(required)*
  - `slug` (string) *(required)*
  - `status` (number) *(required)*
  - `request_id` (string)
  - `suggested_fix` (string)
  - `errors` (array<string>)

#### 403 - Forbidden. The session does not belong to the authenticated user.

**Response Schema:**

- `error` (object) *(required)*
  - `message` (string) *(required)*
  - `code` (number) *(required)*
  - `slug` (string) *(required)*
  - `status` (number) *(required)*
  - `request_id` (string)
  - `suggested_fix` (string)
  - `errors` (array<string>)

#### 404 - Not found. The session does not exist, toolkit not found, or no auth config exists for the toolkit.

**Response Schema:**

- `error` (object) *(required)*
  - `message` (string) *(required)*
  - `code` (number) *(required)*
  - `slug` (string) *(required)*
  - `status` (number) *(required)*
  - `request_id` (string)
  - `suggested_fix` (string)
  - `errors` (array<string>)

#### 500 - Internal server error. An unexpected error occurred while creating the link session.

**Response Schema:**

- `error` (object) *(required)*
  - `message` (string) *(required)*
  - `code` (number) *(required)*
  - `slug` (string) *(required)*
  - `status` (number) *(required)*
  - `request_id` (string)
  - `suggested_fix` (string)
  - `errors` (array<string>)

### Example cURL Request

```bash
curl -X POST "https://backend.composio.dev/api/v3.1/tool_router/session/string/link" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "toolkit": "string",
    "alias": "string",
    "callback_url": "https://example.com",
    "experimental": {
      "account_type": "PRIVATE",
      "acl_config_for_shared": {
        "allow_all_users": true,
        "allowed_user_ids": [
          "..."
        ],
        "not_allowed_user_ids": [
          "..."
        ]
      }
    }
  }'
```