> **Building with AI coding agents?** Install the authstack plugin with one command. This equips your agent with accurate Scalekit implementation patterns.
>
> **Recommended**:
> ```bash
> npx @scalekit-inc/cli setup
> ```
>
> Global:
> ```bash
> npm install -g @scalekit-inc/cli
> scalekit setup
> ```
>
> Supports Claude Code, Cursor, GitHub Copilot, Codex + skills for other Agent Skills-compatible agents.
> Skills: integrate-agentkit, implement-saaskit, add-mcp-oauth, implement-sso, implement-scim.
> [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Create a connected account

`POST /api/v1/connected_accounts`

Creates a connected account for one user and one connection, with credentials your app already holds: OAuth tokens, or an API key or other static credentials. To have the user connect their own account instead, send them an authorization link. Returns the account with its ID and status.

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `connected_account` | object | Yes | Details of the connected account to create. |
| `connected_account.api_config` | object | No | Optional JSON configuration for connector-specific API settings such as rate limits, custom API endpoints, timeouts, or feature flags. |
| `connected_account.authorization_details` | object | No | Authentication credentials for the connected account. Include OAuth tokens (access_token, refresh_token, scopes) or static auth details (API keys, bearer tokens). Can be provided later via update. |
| `connected_account.authorization_details.google_dwd` | object | No | Google Domain-Wide Delegation authentication — used for GOOGLE_DWD connections. Send only subject in requests; access_token, scopes, and token_expires_at are response-only. |
| `connected_account.authorization_details.oauth_token` | object | No | OAuth 2.0 credentials. |
| `connected_account.authorization_details.static_auth` | object | No | Static credentials, such as an API key. |
| `connected_account.authorization_details.trusted_idp` | object | No | Credentials for a connection that signs in through a trusted identity provider, such as AWS Redshift. Send only `db_user`. Responses include `access_key_id` and `expiry`, never the secret key or session token. |
| `connector` | string | Yes | The connection name, as shown in **AgentKit** > **Connections**. |
| `identifier` | string | No | Your app's ID for the user. Use a stable internal ID, not an email address. Required unless you key the account by `organization_id`. |
| `organization_id` | string | No | An organization ID to key the account by instead of `identifier`, such as a Scalekit organization ID. Ignored when `identifier` is set. |
| `user_id` | string | No | A user ID that, with `organization_id`, keys the account to one user in that organization. Ignored when `identifier` is set. |

**Response (200)**

| Name | Type | Description |
| --- | --- | --- |
| `connected_account` | object | The newly created connected account with its unique identifier, status, and complete authorization details including access tokens. |
| `connected_account.api_config` | object | Optional JSON configuration for connector-specific API settings such as rate limits, custom endpoints, or feature flags. |
| `connected_account.authorization_details` | object | The account's credentials. Set the one that matches the connection's auth type - `oauth_token`, `static_auth`, `google_dwd` or `trusted_idp`. |
| `connected_account.authorization_details.google_dwd` | object | Google Domain-Wide Delegation authentication — used for GOOGLE_DWD connections. Send only subject in requests; access_token, scopes, and token_expires_at are response-only. |
| `connected_account.authorization_details.oauth_token` | object | OAuth 2.0 credentials. |
| `connected_account.authorization_details.static_auth` | object | Static credentials, such as an API key. |
| `connected_account.authorization_details.trusted_idp` | object | Credentials for a connection that signs in through a trusted identity provider, such as AWS Redshift. Send only `db_user`. Responses include `access_key_id` and `expiry`, never the secret key or session token. |
| `connected_account.authorization_type` | string (enum) | Type of authorization mechanism used. Specifies whether this connection uses OAuth, API keys, bearer tokens, or other auth methods. One of: `OAUTH`, `API_KEY`, `BASIC_AUTH`, `BEARER_TOKEN`, `CUSTOM`, `BASIC`, `OAUTH_M2M`, `TRELLO_OAUTH1`, `GOOGLE_DWD`, `TRUSTED_IDP`, `SMART_FHIR`, `NO_AUTH`. |
| `connected_account.connection_id` | string | Reference to the parent connection configuration. Links this account to a specific connector setup in your environment. |
| `connected_account.connector` | string | The connection name, as shown in **AgentKit** > **Connections**. |
| `connected_account.id` | string | Unique Scalekit-generated identifier for this connected account. Always prefixed with 'ca_'. |
| `connected_account.identifier` | string | Your app's ID for the user, the value passed when the account was created. |
| `connected_account.is_org_wide_credential` | boolean | Whether this is the shared credential of an org-wide connection, which every user's tool calls on that connection use. `false` for a user's own account. |
| `connected_account.last_used_at` | string | Timestamp when this connected account was last used to make an API call. Useful for tracking active connections. |
| `connected_account.provider` | string | The app the account connects to, such as `GMAIL` or `SLACK`. |
| `connected_account.status` | string (enum) | Current status of the connected account. Indicates if the account is active, expired, pending authorization, or pending user identity verification. One of: `ACTIVE`, `EXPIRED`, `PENDING_AUTH`, `PENDING_VERIFICATION`, `DISCONNECTED`. |
| `connected_account.token_expires_at` | string | Expiration timestamp for the access token. After this time, the token must be refreshed or re-authorized. |
| `connected_account.updated_at` | string | Timestamp when this connected account was last modified. Updated whenever credentials or configuration changes. |

**Errors**

- `400`: Invalid request - missing required fields, invalid authorization details, or validation failed. Error code `RESOURCE_ALREADY_EXISTS` when the user already has a connected account on this connection; update it instead.
- `401`: Authentication required - missing or invalid access token
- `404`: Not found - no connection with this name exists in the environment. Error code `RESOURCE_NOT_FOUND`.

**Request**

```bash
curl -sS -X POST \
  "$SCALEKIT_ENVIRONMENT_URL/api/v1/connected_accounts" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "connector": "gmail",
    "identifier": "user_123",
    "connected_account": {
      "authorization_details": {
        "oauth_token": {
          "access_token": "[ACCESS TOKEN]",
          "refresh_token": "[REFRESH TOKEN]",
          "scopes": [
            "https://www.googleapis.com/auth/gmail.readonly"
          ]
        }
      }
    }
  }'
```

**Response**

```json
{
  "connected_account": {
    "id": "ca_24834495392086178",
    "connection_id": "conn_70219645518265104",
    "connector": "gmail",
    "identifier": "user_123",
    "provider": "GMAIL",
    "authorization_type": "OAUTH",
    "status": "ACTIVE",
    "is_org_wide_credential": false,
    "token_expires_at": "2026-10-02T15:30:00Z",
    "last_used_at": "2026-10-02T14:31:07Z",
    "updated_at": "2026-10-02T14:30:00Z",
    "authorization_details": {
      "oauth_token": {
        "access_token": "[ACCESS TOKEN]",
        "refresh_token": "[REFRESH TOKEN]",
        "scopes": [
          "https://www.googleapis.com/auth/gmail.readonly"
        ]
      }
    }
  }
}
```

**Python SDK:** `scalekit_client.actions.create_connected_account`

Create a new connected account

```python
scalekit_client.actions.create_connected_account(
    connection_name: str,
    identifier: str,
    authorization_details: Optional[Dict[str, Any]] = None,
    organization_id: Optional[str] = None,
    user_id: Optional[str] = None,
    api_config: Optional[Dict[str, Any]] = None,
) -> CreateConnectedAccountResponse
```

Example:

```python
result = scalekit_client.actions.create_connected_account(
    connection_name="gmail",
    identifier="user_123",
    authorization_details={
        "oauth_token": {
            "access_token": "[ACCESS TOKEN]",
            "refresh_token": "[REFRESH TOKEN]",
            "scopes": ["https://www.googleapis.com/auth/gmail.readonly"],
        },
    },
)
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `connection_name` | `str` | Yes | The connection name, as shown in **AgentKit** > **Connections**. |
| `identifier` | `str` | Yes | Your app's ID for the user, the same value you used when the user connected. Use a stable internal ID, not an email address. |
| `authorization_details` | `Optional[Dict[str, Any]]` | No | Authorization details (OAuth token or static auth) |
| `organization_id` | `Optional[str]` | No | Organization ID |
| `user_id` | `Optional[str]` | No | User ID |
| `api_config` | `Optional[Dict[str, Any]]` | No | Optional API configuration for the connected account |

Returns `CreateConnectedAccountResponse`: The created connected account details

**Node.js SDK:** `scalekit.actions.createConnectedAccount`

Create a new connected account. This helper accepts a high-level payload and builds the underlying CreateConnectedAccount message.

```ts
scalekit.actions.createConnectedAccount(
  params: {
    connectionName: string;
    identifier: string;
    authorizationDetails: MessageInitShape<typeof CreateConnectedAccountSchema>['authorizationDetails'];
    organizationId?: string;
    userId?: string;
    apiConfig?: Record<string, unknown>;
  },
): Promise<CreateConnectedAccountResponse>
```

Example:

```ts
const result = await scalekit.actions.createConnectedAccount({
  connectionName: "gmail",
  identifier: "user_123",
  authorizationDetails: {
    details: {
      case: "oauthToken",
      value: {
        accessToken: "[ACCESS TOKEN]",
        refreshToken: "[REFRESH TOKEN]",
        scopes: ["https://www.googleapis.com/auth/gmail.readonly"],
      },
    },
  },
});
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `connectionName` | `string` | Yes | The connection name, as shown in **AgentKit** > **Connections**. |
| `identifier` | `string` | Yes | Your app's ID for the user, the same value you used when the user connected. Use a stable internal ID, not an email address. |
| `authorizationDetails` | `MessageInitShape<typeof CreateConnectedAccountSchema>['authorizationDetails']` | Yes | The user's credentials: OAuth tokens as `{ case: "oauthToken", value }`, or an API key or other static values as `{ case: "staticAuth", value }`. To have the user connect their own account instead, use `getAuthorizationLink`. |
| `organizationId` | `string` | No | An organization ID to key the account by instead of `identifier`, such as a Scalekit organization ID. Ignored when `identifier` is set. |
| `userId` | `string` | No | A user ID that, with `organization_id`, keys the account to one user in that organization. Ignored when `identifier` is set. |
| `apiConfig` | `Record<string, unknown>` | No | Optional JSON configuration for connector-specific API settings such as rate limits, custom API endpoints, timeouts, or feature flags. |

Returns `Promise<CreateConnectedAccountResponse>`.

**Used in**

- [Apify Actor with per-user OAuth via Scalekit](https://docs.scalekit.com/cookbooks/apify-actor-per-user-oauth/)
- [Authorize a user](https://docs.scalekit.com/agentkit/tools/authorize/)
- [Build a daily briefing agent with Vercel AI SDK and Scalekit AgentKit](https://docs.scalekit.com/cookbooks/daily-briefing-agent/)
- [Build a Mastra agent with Scalekit AgentKit tools](https://docs.scalekit.com/cookbooks/mastra-agentkit/)
- [Build a multi-agent email triage crew with CrewAI](https://docs.scalekit.com/cookbooks/crewai-agentkit-email-triage/)
- [Build a multi-user GitHub PR summarizer agent](https://docs.scalekit.com/cookbooks/render-github-pr-summarizer/)
- [Build an agent that books meetings and drafts emails](https://docs.scalekit.com/cookbooks/schedule-meeting-and-draft-email/)
- [FastRouter + Scalekit tool calling](https://docs.scalekit.com/cookbooks/fastrouter-agentkit-tool-calling/)
- [Manage connected accounts](https://docs.scalekit.com/agentkit/connected-accounts/)
- [Migrate from Composio to Scalekit](https://docs.scalekit.com/agentkit/advanced/migrate-from-composio/)
- [Quickstart](https://docs.scalekit.com/agentkit/quickstart/)
- [Trace AgentKit tool calls in LangSmith](https://docs.scalekit.com/cookbooks/langsmith-tracing-agentkit/)

Also called by `scalekit_client.actions.get_or_create_connected_account` (Python), `scalekit.actions.getOrCreateConnectedAccount` (Node.js).


Part of [Connected accounts](https://docs.scalekit.com/agentkit/reference/connected-accounts/) in the [AgentKit API reference](https://docs.scalekit.com/agentkit/reference/). Authentication: https://docs.scalekit.com/agentkit/reference/authentication.md. Errors and rate limits: https://docs.scalekit.com/agentkit/reference/errors.md. Pagination: https://docs.scalekit.com/agentkit/reference/pagination.md


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
