> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useparagon.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Multi-Account Authorization

> Use the SDK to connect multiple accounts for the same integration.

Multiple Account Authorizations is a set of SDK options that enables you to connect multiple accounts of the same integration type for a Connected User.

For example, one Connected User can connect a Google Calendar integration for both their Google Workspace account and personal Google account.

## Supported Features

| Feature                                | Supported                                                  |
| -------------------------------------- | ---------------------------------------------------------- |
| [Workflows](/workflows/overview)       | Yes                                                        |
| [ActionKit](/actionkit/overview)       | Yes (via `X-Paragon-Credential` header)                    |
| [Proxy API](/apis/proxy)               | Yes (via `selectedCredentialId` or `X-Paragon-Credential`) |
| [Managed Sync](/managed-sync/overview) | Yes (via `credentialId` in request body)                   |

## Getting Started

**Connecting new accounts**

To get started with Multiple Account Authorizations, you can pass in `allowMultipleCredentials` to `paragon.installIntegration`:

```javascript theme={null}
// Connect a new Google Calendar account
paragon.installIntegration("googleCalendar", {
    allowMultipleCredentials: true,

    // Set to true to show User Settings after installation:
    showPortalAfterInstall: true
});
```

This function starts the connection process for a new account of an integration. After the user has connected, you can optionally show the Connect Portal for presenting any User Settings that are used to configure the integration.

**Listing accounts**

Your UI must be able to render a list of each account your user has connected for an integration. Use `paragon.getUser` to retrieve this list:

```javascript theme={null}
const user = paragon.getUser();

// An array of all Google Calendar accounts the user has connected:
user.integrations.googleCalendar.allCredentials;
```

Each account ("credential") will have an ID that can be used to present the Connect Portal for the account, remove the account, or route requests to the account.

Use `paragon.subscribe` to listen for change events to the Paragon user object, if your UI updates dynamically.

**Managing existing accounts**

You can allow your users to manage User Settings for a specific account using the Connect Portal by passing `selectedCredentialId` to `paragon.connect`:

```javascript theme={null}
// Modify User Settings for an existing Google Calendar account
paragon.connect("googleCalendar", {
    selectedCredentialId: "a5e995c2-7709-43fd-9cdf-f759faa52497"
});
```

**Removing existing accounts**

You can disconnect an existing account by passing `selectedCredentialId` to `paragon.uninstallIntegration`:

```javascript theme={null}
// Disconnect an existing Google Calendar account
paragon.uninstallIntegration("googleCalendar", {
    selectedCredentialId: "a5e995c2-7709-43fd-9cdf-f759faa52497" 
});
```

## Usage

A subset of SDK functions can be passed an additional parameter for Multiple Account Authorizations, as outlined below.

In general, to use Multiple Account Authorizations, you will need to:

* Use `user.integrations.[integration].allCredentials` (a field returned in [`getUser`](/apis/api-reference/multi-account-authorization#getuser->-paragonuser)) to display multiple connected accounts in your Integrations UI.
* Update references to [`connect`](/apis/api-reference#connect-integrationtype%3A-string%2C-installoptions%3F%3A-installoptions) (or [`installIntegration`](/apis/api-reference/multi-account-authorization#installintegration-integrationtype%3A-string%2C-options%3F%3A-integrationinstalloptions->-promise) and [`uninstallIntegration`](/apis/api-reference/multi-account-authorization#.uninstallintegration-integrationtype%3A-string%2C-options%3F%3A-integrationuninstalloptions->-promise)) to use the SDK with Multiple Account Authorizations enabled.
* Update references to [`paragon.request`](/apis/api-reference/multi-account-authorization#request-integrationtype%3A-string%2C-path%3A-string%2C-requestoptions%3A-requestoptions-→-promise) and [`paragon.workflow`](/apis/api-reference/multi-account-authorization#workflow-workflowid%3A-string%2C-options%3A-fetchoptions) (and API equivalents) to make sure that a specific account is targeted for a given integration type.

App Events and Workflows do not need to be updated to support Multiple Account Authorizations.

## Access Control

If you are using Multi-Account Authorization to enable multiple users within one organization to connect their individual credentials within one Connected User, use JWT Permissions to restrict each user's access to only the accounts they have connected:

<Card title="JWT Permissions" icon="lock" horizontal href="/apis/api-reference/jwt-permissions" arrow>
  Learn more abut implementing JWT Permissions to control access to credentials.
</Card>

## Reference

### <span id="getuser">.getUser() → ParagonUser</span>

Call `.getUser` to retrieve the currently authenticated user and their connected integration state.

With Multiple Account Authorizations, the `getUser()` method additionally returns `allCredentials`, an array of connected accounts for a given integration.

<CodeGroup>
  ```javascript JavaScript SDK theme={null}
  paragon.getUser();

  {
    authenticated: true,
    userId: "xyz", // The user ID you specified in the signed JWT
    integrations: {
      salesforce: {
        enabled: true,
        allCredentials: [
          {
            id: "a5e995c2-7709-43fd-9cdf-f759faa52497",
            dateCreated: "2023-05-30T22:33:20.349Z",
            dateUpdated: "2023-05-30T22:33:20.349Z",
            projectId: "d1f142cd-1dfe-4d76-ab4c-8f64901a9c5c",
            integrationId: "8aaad9ff-5adb-433c-a17b-da093f9d4528",
            personaId: "30975f6a-c50c-4e74-914a-3eb700db8b05",
            config: { configuredWorkflows: { ... } },
            isPreviewCredential: false,
            providerId: "1223115691",
            providerData: {},
            status: "VALID",
            dateRefreshed: "2023-05-30T22:33:20.349Z",
            dateValidUntil: "2023-05-30T23:33:17.809Z",
            refreshFailureCount: 0,
            isRefreshing: false,
            externalId: "my-external-id", // Present if set via connect() or installIntegration()
          },
        ],
        configuredWorkflows: {},
        credentialId: "a5e995c2-7709-43fd-9cdf-f759faa52497",
        credentialStatus: "VALID",
        providerId: "1223115691",
        providerData: {},
      },
      shopify: {
        enabled: false,
      },
    },
  };
  ```

  ```bash REST API theme={null}
  GET https://api.useparagon.com/projects/<Paragon Project ID>/sdk/me

  Authorization: Bearer <Paragon User Token>
  Content-Type: application/json

  {
    authenticated: true,
    userId: "xyz", // The user ID you specified in the signed JWT
    integrations: {
      salesforce: {
        enabled: true,
        allCredentials: [
          {
            id: "a5e995c2-7709-43fd-9cdf-f759faa52497",
            dateCreated: "2023-05-30T22:33:20.349Z",
            dateUpdated: "2023-05-30T22:33:20.349Z",
            projectId: "d1f142cd-1dfe-4d76-ab4c-8f64901a9c5c",
            integrationId: "8aaad9ff-5adb-433c-a17b-da093f9d4528",
            personaId: "30975f6a-c50c-4e74-914a-3eb700db8b05",
            config: { configuredWorkflows: {} },
            isPreviewCredential: false,
            providerId: "1223115691",
            providerData: {},
            status: "VALID",
            dateRefreshed: "2023-05-30T22:33:20.349Z",
            dateValidUntil: "2023-05-30T23:33:17.809Z",
            refreshFailureCount: 0,
            isRefreshing: false,
            externalId: "my-external-id",
          }
        ],
        configuredWorkflows: {},
        credentialId: "a5e995c2-7709-43fd-9cdf-f759faa52497",
        credentialStatus: "VALID",
        providerId: "1223115691",
        providerData: {},
      },
      shopify: {
        enabled: false,
      }
    }
  }
  ```
</CodeGroup>

### <span id="installintegration">.installIntegration(integrationType: string, options?: IntegrationInstallOptions) → Promise</span>

* **Full docs**: [.installIntegration(integrationType: string, installOptions?: InstallOptions) → Promise](/apis/api-reference#installintegration-integrationtype-string-installoptions-installoptions-→-promise\<integrationinstallevent>)
* **Additional options**: If `allowMultipleCredentials` is specified as `true` in the `options` object, this function will not throw an error if the user already has this integration installed.

You can use the resulting Promise to get the newly created credential.

```js JavaScript SDK theme={null}
const { credential } = await paragon.installIntegration("googledrive", {
    allowMultipleCredentials: true
});
```

**Replacing an account**

You can replace one of your user's existing connected accounts with the `selectedCredentialId` property. This option replaces the underlying connected account, keeping their enabled workflows and settings intact.

```js JavaScript SDK theme={null}
paragon.installIntegration("googledrive", {
    allowMultipleCredentials: true,
    selectedCredentialId: "0d2cca60-268b-45f1-ac5e-af6aad403d8c"
});
```

### <span id="uninstallintegration">.uninstallIntegration(integrationType: string, options?: IntegrationUninstallOptions) → Promise</span>

Call `.uninstallIntegration()` to disconnect an integration for the authenticated user.

* **Full docs**: [.uninstallIntegration(integrationType: string) → Promise](/apis/api-reference#uninstallintegration-integrationtype-string->-promise)
* **Additional options:** `selectedCredentialId` (SDK) or `X-Paragon-Credential` (API) can be used to select a specific account to uninstall.

<CodeGroup>
  ```javascript JavaScript SDK theme={null}
  paragon.uninstallIntegration("googledrive", {
      selectedCredentialId: "de06dea8-8680-483c-95ea-cfcf66582c96"
  });
  ```

  ```bash REST API theme={null}
  DELETE https://api.useparagon.com/projects/<Project ID>/sdk/integrations/<Integration ID>

  Authorization: Bearer <Paragon User Token>
  X-Paragon-Credential: de06dea8-8680-483c-95ea-cfcf66582c96
  ```
</CodeGroup>

### <span id="connect">.connect(integrationType: string, options: IntegrationInstallOptions) → Promise</span>

With Multiple Account Authorizations, use `.connect` to present the Connect Portal for an *existing* account for the intended integration. [`.installIntegration`](apis/api-reference/multi-account-authorization#installintegration-integrationtype%3A-string%2C-options%3F%3A-integrationinstalloptions->-promise) is used to connect *new* accounts.

* The Connect Portal can show the settings and workflows enabled for one account at a time, set by the `selectedCredentialId` property. If `selectedCredentialId` is not defined, the Connect Portal will use the first account available.
* When the Connect Portal appears, a user can enable or disable workflows, update User Settings, and disconnect the account that is selected.

```js JavaScript SDK theme={null}
// Connect a new account for this integration.
// NOTE: You must use `.installIntegration` rather than `.connect`.
paragon.installIntegration("salesforce", {
    allowMultipleCredentials: true
})

// Show the Connect Portal to configure an existing account for this integration.
paragon.connect("salesforce", {
    selectedCredentialId: "de06dea8-8680-483c-95ea-cfcf66582c96"
});
```

### <span id="request">.request(integrationType: string, path: string, requestOptions: RequestOptions) → Promise</span>

Call `.request` to send an API request to a third-party integration on behalf of one of your users.

* **Full docs**: [.request(integrationType: string, path: string, requestOptions: RequestOptions) → Promise](/apis/api-reference#request-integrationtype-string-path-string-requestoptions-requestoptions-→-promise)
* **Additional options:** `selectedCredentialId` (SDK) or `X-Paragon-Credential` (API) can be used to select a specific account to use with the [Proxy API](/apis/proxy) or [ActionKit](/actionkit/overview).

<CodeGroup>
  ```js JavaScript SDK theme={null}
  await paragon.request('slack', '/chat.postMessage', {
  	method: 'POST',
  	body: {
  		channel: 'CXXXXXXX0' // Channel ID,
  		text: 'This message was sent with Paragon Connect :exploding_head:'
  	},
  	selectedCredentialId: "de06dea8-8680-483c-95ea-cfcf66582c96"
  });
  ```

  ```bash REST API theme={null}
  POST https://proxy.useparagon.com/projects/<Paragon Project ID>/sdk/proxy/slack/chat.postMessage

  Authorization: Bearer <Paragon User Token>
  Content-Type: application/json
  X-Paragon-Credential: de06dea8-8680-483c-95ea-cfcf66582c96

  { 
      "channel": "CXXXXXXX0", 
      "text": "This message was sent with Paragon Connect :exploding_head:" 
  }
  ```
</CodeGroup>

### <span id="pickerInit">picker.init(initConfig)</span>

You can use the Paragon SDK to allow your user to select files from a File Storage integration in your app. After constructing a new instance of the [ExternalFilePicker](/apis/api-reference#externalfilepicker), you can initialize a file picker with required configuration `initConfig`, including the `selectedCredentialId` for the user.

Required configuration varies per integration; see [integration-specific documentation](/apis/api-reference#supported-integrations-for-externalfilepicker) for specific details.

This function loads required JS dependencies into the page, if they have not already been loaded. Other methods, like `.open` and `.getInstance`, cannot be called until the Promise returned by `.init` is resolved.

**Example:**

```js theme={null}
await picker.init({ 
    // Google Developer Key
    developerKey: "AIzaS...",
    // identifier for your Google App
    appId: "457...",
    selectedCredentialId: "de06dea8-8680-483c-95ea-cfcf66582c96"
});
```

### <span id="workflow">.workflow(workflowId: string, options: FetchOptions)</span>

Call `.workflow()` to trigger a Paragon workflow that sends a custom response back to your app. Note: The workflow must be enabled and use a Request-type trigger.

* **Full docs**: [.workflow(workflowId: string, options: FetchOptions)](/apis/api-reference#workflow-workflowid-string-options-fetchoptions)
* **Additional options:** `selectedCredentialId` (SDK) or `X-Paragon-Credential` (API) can be used to select a specific account for which to trigger a workflow. The Credential ID that is used will be recorded for viewing in the [Monitoring Workflows page](workflows/viewing-workflow-executions).

<CodeGroup>
  ```javascript JavaScript SDK theme={null}
  // Trigger the "Lead Created" workflow
  await paragon.workflow("<workflow_id>", {
    body: {
      "email": "bowie@useparagon.com",
      "first_name": "Bowie",
      "last_name": "Foo"
    },
    selectedCredentialId: "de06dea8-8680-483c-95ea-cfcf66582c96"
  });
    
  ```

  ```bash REST API theme={null}
  // Trigger the "Lead Created" Workflow
  POST https://api.useparagon.com/projects/<Paragon Project ID>/sdk/triggers/<Workflow ID>

  Authorization: Bearer <Paragon User Token>
  Content-Type: application/json
  X-Paragon-Credential: de06dea8-8680-483c-95ea-cfcf66582c96

  {
    "email": "bowie@useparagon.com",
    "first_name": "Bowie",
    "last_name": "Foo
  }
  ```
</CodeGroup>
