> ## 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.

# Headless Connect Portal

> Bring your existing components or design system into your Paragon integrations experience with the Headless Connect Portal.

The Headless Connect Portal can be used with your own UI components or design system to make your integrations feel native to the design of your app, while leveraging the SDK for all of the backend details of connecting and configuring your users' integrations.

Headless mode still provides **fully managed authentication**, so you don't need to worry about managing, storing, or refreshing your customers' credentials.

## Example Implementation

Below is an end-to-end example implemented with React and [shadcn/ui](https://ui.shadcn.com/) components (no pre-built Paragon components are used):

<Frame caption="An example implementation of the Headless Connect Portal, using shadcn/ui components and the Paragon SDK">
  <img src="https://mintcdn.com/paragon/esBRs8T9ngw7PCPW/assets/connect-headless-example.gif?s=ce92cc768d1fae8ef98adbb97bc62020" alt="" width="800" height="509" data-path="assets/connect-headless-example.gif" />
</Frame>

We have open-sourced the above implementation in a public repository here:

<Card title="useparagon/connect-headless-example" icon="github" href="https://github.com/useparagon/connect-headless-example" horizontal>
  An end-to-end implementation example of the Headless Connect Portal using
  React
</Card>

You can use the example implementation or any of its components as a starting point for your application, or read on to learn how to implement it yourself.

## Usage

To implement the Headless Connect Portal, use the SDK to implement the following product surfaces in your app:

* **Integrations Catalog**: Listing all available integrations in a catalog to allow your users to discover integrations and connect their accounts.
* **Integration Install / Uninstall Flow**: Guiding your user through the install stages of any integration, including the OAuth 2.0 flow (if required for the integration)
* **User Settings and Workflow Configuration**: Providing inputs for users to configure [User Settings](/connect-portal/workflow-user-settings) for their integration.

Follow the sections below to learn how to implement each of these product surfaces using the Paragon SDK.

<Info>
  **Have you implemented SDK authentication?**

  The Usage guide below assumes that you have already implemented the basics of SDK authentication described in [Getting Started](/getting-started/installing-the-connect-sdk). All of the functions below should be called *after* SDK authentication is completed.
</Info>

### Enabling Headless Mode

To turn on Headless mode for the SDK, call the `setHeadless()` function:

```js theme={null}
import { paragon } from "@useparagon/connect";

paragon.setHeadless(true);
```

This only needs to be called once after SDK initialization to use the Headless Connect Portal functions.

### Integrations Catalog

In your app's Integrations Catalog or Settings view, list available integrations from your Paragon project to allow your users to discover integrations and connect their accounts:

<Frame>
  <img src="https://mintcdn.com/paragon/l1vzjNTWrUIk0ls8/assets/headless-integrations-catalog.png?fit=max&auto=format&n=l1vzjNTWrUIk0ls8&q=85&s=8483f9530406362c714d85d82dddb06d" alt="" width="2550" height="514" data-path="assets/headless-integrations-catalog.png" />
</Frame>

You can render this view by calling `paragon.getIntegrationMetadata()`:

```js theme={null}
paragon.getIntegrationMetadata();
```

Each entry in the returned list will be an object with the integration's display metadata, including the brand name, icon, and accent color:

```js theme={null}
[
  {
    type: "salesforce",
    name: "Salesforce",
    brandColor: "#057ACF",
    icon: "https://cdn.useparagon.com/latest/dashboard/public/integrations/salesforce.svg",
  },
];
```

<Columns cols={2}>
  <Card
    title="Integrations Catalog Example"
    cta="See code"
    href="https://github.com/useparagon/connect-headless-example/blob/main/src/components/feature/integration/integration-list.tsx
"
    arrow={false}
  >
    See our reference implementation of the Integrations Catalog in the example
    repo.
  </Card>

  <Card title="SDK Reference" cta="See reference" href="/apis/api-reference#getintegrationmetadata">
    Learn more about `getIntegrationMetadata()` in the SDK Reference.
  </Card>
</Columns>

#### Integration Detail View

As a part of your catalog, you may want to show users additional information when they click on an integration (or inline with the catalog):

<Frame caption="A detail view of the Slack integration, after clicking on the Slack entry in the Integrations Catalog">
  <img src="https://mintcdn.com/paragon/l1vzjNTWrUIk0ls8/assets/headless-modal-detail.png?fit=max&auto=format&n=l1vzjNTWrUIk0ls8&q=85&s=cb5d72c6ac78412c0a322ec86a10e4ae" alt="Headless Connect Portal modal" width="1980" height="1384" data-path="assets/headless-modal-detail.png" />
</Frame>

To get the additional user-facing descriptions and informational text about the integration [configured in your Paragon dashboard](/connect-portal/connect-portal-customization), use [`.getIntegrationConfig`](/apis/api-reference#getintegrationconfig):

```js theme={null}
paragon.getIntegrationConfig("slack");
```

This will return an object with the descriptions, User Settings, and Workflows associated with the integration:

```json Response expandable theme={null}
{
  "shortDescription": "Send notifications to Slack",
  "longDescription": "Connect your Slack workspace to receive notifications and alerts in Slack. Stay connected to important activity by bringing it all together in your Slack workspace.\n\nOur Slack integration enables you to:\n\n• Receive alerts and notifications in your Slack workspace\n• Notify or DM specific team members based on certain activity",
  "availableUserSettings": [
    {
      "id": "2d5662c9-6750-46c2-8588-2ac904532efb",
      "type": "DYNAMIC_ENUM",
      "title": "Channel",
      "required": false,
      "sourceType": "channels"
    }
  ],
  "availableWorkflows": [
    {
      "id": "2248335c-671c-47e4-b9a0-3641a9f2d301",
      "inputs": [],
      "infoText": "Send a Slack notification when a Task is created",
      "defaultEnabled": false,
      "description": "Send Slack Notification"
    }
  ],
  "hiddenWorkflows": []
}
```

<Columns cols={2}>
  <Card
    title="Integration Detail View Example"
    cta="See code"
    href="https://github.com/useparagon/connect-headless-example/blob/main/src/components/feature/integration/integration-modal/integration-modal.tsx#L34-L36
"
    arrow={false}
  >
    See our reference implementation of the Integration Detail View in the
    example repo.
  </Card>

  <Card title="SDK Reference" cta="See reference" href="/apis/api-reference#getintegrationconfig">
    Learn more about `getIntegrationConfig()` in the SDK Reference.
  </Card>
</Columns>

#### Displaying Account State

To display your user's account connection status in the Integrations Catalog (for example, showing a "Manage" button instead of a "Connect" button for integrations they have already installed), call `.getUser` to get the user's account state and `.subscribe` to react to state changes.

```js Getting account state with getUser expandable theme={null}
paragon.getUser();

// Returns:
{
  "authenticated": true,
  "userId": "user-id",
  "integrations": {
    "salesforce": {
      "enabled": false,
      "configuredWorkflows": {}
    },
    "slack": {
      "enabled": true,
      "configuredWorkflows": {},
      "credentialStatus": "VALID",
      "credentialId": "81af6717-9476-458d-8c29-f0aee7ce6d12",
      "providerId": "TM7FL705V",
      "providerData": {}
    },
    "hubspot": {
      "enabled": false,
      "configuredWorkflows": {}
    }
  },
  "meta": {}
}
```

We can use the result of this object to conditionally show a **Connect** or **Manage** button, depending on the value of `user.integrations[integrationType].enabled`.

You can also react to changes in your UI by setting up `.subscribe` handlers:

```js Example component using subscribe() to react to user state changes expandable theme={null}
function MyComponent() {
  const [user, setUser] = useState<AuthenticatedConnectUser | undefined>();

  // Listen for account state changes
  useEffect(() => {
    const listener = () => {
      if (paragon) {
        const authedUser = paragon.getUser();
        if (authedUser.authenticated) {
          setUser({ ...authedUser });
        }
      }
    };
    listener();
    paragon?.subscribe("onIntegrationInstall", listener);
    paragon?.subscribe("onIntegrationUninstall", listener);
    return () => {
      paragon?.unsubscribe("onIntegrationInstall", listener);
      paragon?.unsubscribe("onIntegrationUninstall", listener);
    };
  }, [paragon]);
}
```

<Card title="SDK Reference" href="/apis/api-reference#getuser" horizontal arrow>
  Learn more about `getUser()` in the SDK Reference.
</Card>

### Integration Install / Uninstall Flow

Once a user expresses intent to connect their account, guide them through an **Install Flow** using the Paragon SDK:

<Frame caption="Install Flow example for Shopify">
  <img src="https://mintcdn.com/paragon/l1vzjNTWrUIk0ls8/assets/headless-install-flow-2.gif?s=43c2d7834765e056dd26f775b4bd879e" alt="" width="800" height="624" data-path="assets/headless-install-flow-2.gif" />
</Frame>

To implement an Install Flow, your app will need to handle the following stages of the installation process which should take place in your app (the stages used by each integration will vary):

* Account Type selection (e.g. Salesforce Production vs. Salesforce Sandbox) -- `AccountTypeStage`
* Pre-OAuth / API Key inputs (e.g. Stripe API Key input, Shopify Store URL) -- `PreOptionsStage`
* Post-OAuth inputs (e.g. Atlassian site, SharePoint site selection) -- `PostOptionsStage`
* Instructional content (e.g. Salesforce package installation) -- `InstructionStage`

<Info>
  See a full reference of install flow stages and their properties in the [SDK Reference](/apis/api-reference#installflowstage).
</Info>

Any redirection or popup window that is required for OAuth will automatically occur between stages. The SDK will internally manage all state for the popup window and OAuth prompt, but if an error occurs during the install flow, you can receive errors using the `onError` callback and prompt users of any issues.

Begin an Install Flow by calling `paragon.installFlow.start`:

```js theme={null}
paragon.installFlow
  .start(props.integration, {
    onNext: (next) => {
      // Handle next install stage by presenting or updating UI for user input
    },
    onComplete: () => {
      // Installation has completed successfully
    },
    onError: (error, errorContext) => {
      // Handle error messaging
    }
  });
```

After calling `.start`, you may receive required install stages in the `onNext` callback (depending on the specific install flow required by the integration).

To handle each of the install stages in your app, you will need to:

1. Receive the stage details in the `onNext` callback.
2. Render the appropriate UI for your user to provide the necessary details in that stage.
   <Info>
     For the `PostOptionsStage`, refer to [the User Settings docs](#exposing-user-settings) below for help rendering integration-specific dropdown inputs.
   </Info>
3. Update SDK state with the user's inputs by calling one of:
   * [`installFlow.setAccountType`](/apis/api-reference#setaccounttype)
   * [`installFlow.setPreOptions`](/apis/api-reference#setpreoptions)
   * [`installFlow.setPostOptions`](/apis/api-reference#setpostoptions)

#### Example Install Flow

Here's a step-by-step example for how these stages would be implemented for Salesforce account types:

1. **Receive the `AccountTypeStage` in `onNext` handler:**
   ```js theme={null}
   paragon.installFlow.start("salesforce", {
     onNext: (next) => {
       if (next.stage === "accountType") {
         setAccountTypes(next.stage.options);
         // [{ "id": "default", "accountDescription": "Production Account", "scheme": "oauth" }, {...}, {...}]
       }
     },
   });
   ```
2. **Render account type options for your user to select the available types:**
   ```jsx theme={null}
   return accountTypes.map((accountType) => {
     return (
       <Button
         key={accountType.id}
       >
         {accountType.accountDescription}
       </Button>
     );
   });
   ```
   <Frame caption="Example UI rendered by above code">
     <img src="https://mintcdn.com/paragon/l1vzjNTWrUIk0ls8/assets/headless-account-types.png?fit=max&auto=format&n=l1vzjNTWrUIk0ls8&q=85&s=813a2b4886f5222855619828b57d91a1" alt="Account Types selector" width="1808" height="608" data-path="assets/headless-account-types.png" />
   </Frame>
3. **Update SDK state with the user's inputs:**

   Bind the `onClick` handler for the account type selection buttons to confirm the user's selection and start the OAuth flow.

   ```jsx theme={null}
   return accountTypes.map((accountType) => {
     return (
       <Button
         key={accountType.id}
         onClick={() => paragon.installFlow.setAccountType(accountType.id)} // [!code ++]
       >
         {accountType.accountDescription}
       </Button>
     );
   });
   ```

To implement the other Install Flows, check out our example implementation or SDK Reference:

<Columns cols={2}>
  <Card title="Integration Install Flow Example" cta="See code" href="https://github.com/useparagon/connect-headless-example/blob/5e32d8b/src/components/feature/integration/integration-modal/integration-modal.tsx#L53-L92" arrow={false}>
    See our reference implementation of the Integration Install Flow in the
    example repo.
  </Card>

  <Card title="SDK Reference" cta="See reference" href="/apis/api-reference#installflow">
    Learn more about `installFlow` and all related methods in the SDK Reference.
  </Card>
</Columns>

#### Uninstalling Integrations

When a user requests to disconnect their account, call `uninstallIntegration` to remove their account:

```js theme={null}
async function onClickUninstall() {
  setUninstalling(true);
  await paragon.uninstallIntegration(props.integration);
  setUninstalling(false);
}
```

This function returns a Promise that resolves when the account has been fully disconnected from Paragon (including any workflows or settings they may have configured).

<Card title="SDK Reference" href="/apis/api-reference#uninstallintegration" horizontal arrow>
  Learn more about `uninstallIntegration()` in the SDK Reference.
</Card>

### User Settings and Workflow Configuration

After your user has connected an integration, show a Configuration screen with your configured [User Settings](/connect-portal/workflow-user-settings) to customize their integration, like a Salesforce Field Mapping or a Google Drive Folder to sync files from.

If you are using [Workflows](/workflows/overview) and want your users to have controls to opt-in or out of specific Workflows, you can render toggles to enable or disable Workflows.

<Frame caption="A configuration screen to customize the Google Drive integration with User Settings">
  <img src="https://mintcdn.com/paragon/l1vzjNTWrUIk0ls8/assets/headless-user-settings.png?fit=max&auto=format&n=l1vzjNTWrUIk0ls8&q=85&s=0a337cced6be9182801001fc9ac84aca" alt="Google Drive User Settings" width="1722" height="1064" data-path="assets/headless-user-settings.png" />
</Frame>

You can use the [`getIntegrationConfig`](/apis/api-reference#getintegrationconfig) method to get all the User Settings that you have configured for this integration's Connect Portal:

```js theme={null}
paragon.getIntegrationConfig(type);
```

User Settings will be available as the `availableUserSettings` key of the response.

```json Response focus={2-10} expandable theme={null}
{
  "availableUserSettings": [
    {
      "id": "2d5662c9-6750-46c2-8588-2ac904532efb",
      "type": "DYNAMIC_ENUM",
      "title": "Channel",
      "required": false,
      "sourceType": "channels"
    }
  ],
  "shortDescription": "Send notifications to Slack",
  "longDescription": "Connect your Slack workspace to receive notifications and alerts in Slack. Stay connected to important activity by bringing it all together in your Slack workspace.\n\nOur Slack integration enables you to:\n\n• Receive alerts and notifications in your Slack workspace\n• Notify or DM specific team members based on certain activity",
  "availableWorkflows": [
    {
      "id": "2248335c-671c-47e4-b9a0-3641a9f2d301",
      "inputs": [],
      "infoText": "Send a Slack notification when a Task is created",
      "defaultEnabled": false,
      "description": "Send Slack Notification"
    }
  ],
  "hiddenWorkflows": []
}
```

#### Exposing User Settings

User Settings are inputs that appear during the install or configure stage of the Connect Portal, like the Folder input in the example above. Your implementation should render inputs when:

* Your user is prompted with pre-OAuth options (`PreOptionsStage`)
* Your user is prompted with post-OAuth options (`PostOptionsStage`)
  * For both `PreOptionsStage` and `PostOptionsStage`, User Settings objects can be found in `stage.options`.
* Your user is configuring integration-level or workflow-level [User Settings](/connect-portal/workflow-user-settings)
  * User Settings objects can be found in [`getIntegrationConfig`](/apis/api-reference#getintegrationconfig), under `availableUserSettings` and `availableWorkflows[n].inputs`.

Some User Settings (such as `SidebarInputType.DynamicEnum` or `SidebarInputType.FieldMapping`) will require you to render a dynamic list of options from the integration (a "data source"). You can use the following functions to help load this list:

* [`getSourcesForInput`](/apis/api-reference#getsourcesforinput) - Get the data sources needed to render a dynamic input. Returns the appropriate data source objects which can be passed directly to `getFieldOptions`.
* [`getFieldOptions`](/apis/api-reference#getfieldoptions) - Load a page of options from a data source to show in a dropdown input.

```js DynamicEnum input expandable theme={null}
let config = paragon.getIntegrationConfig("slack");
let input = config.availableUserSettings[0];
// { id: "...", type: "DYNAMIC_ENUM", title: "Channel", sourceType: "channels" }

let sources = paragon.getSourcesForInput("slack", input);
// { kind: "single", source: { type: "DYNAMIC_DATA_SOURCE", cacheKey: "channels", ... } }

// Load options using the source object:
if (sources?.kind === "single") {
  await paragon.getFieldOptions({
    integration: "slack",
    source: sources.source,
  });
  // { data: [{ label: "#general", value: "general" }, ...], nextPageCursor: "..." }
}
```

For compound inputs like Field Mapping, `getSourcesForInput` returns all the necessary data sources at once:

```js Field Mapping input expandable theme={null}
let config = paragon.getIntegrationConfig("salesforce");
let input = config.availableUserSettings[0];
// { id: "...", type: "FIELD_MAPPER", title: "Map fields for a Task", sourceType: "customObjectMapping" }

let sources = paragon.getSourcesForInput("salesforce", input);
// { kind: "fieldMapper", recordSource: {...}, fieldSource: {...} }

if (sources?.kind === "fieldMapper") {
  // Load Record Types:
  await paragon.getFieldOptions({
    integration: "salesforce",
    source: sources.recordSource,
  });

  // Load Fields for a selected record type:
  await paragon.getFieldOptions({
    integration: "salesforce",
    source: sources.fieldSource,
    parameters: [{
      key: sources.recordSource.cacheKey,
      source: { type: "VALUE", value: "Task" },
    }],
  });
}
```

You can see a full list of input types that are used by the Connect Portal and must be rendered by your implementation in [Input Types Reference](/connect-portal/input-types-reference). Alternatively, you can start by using our React-based input renderer in our [reference implementation](https://github.com/useparagon/connect-headless-example/blob/main/src/components/feature/integration/integration-modal/components/integration-settings.tsx).

#### Defining Custom Data Sources

If your Connect Portal inputs use [Custom Dropdowns](/connect-portal/workflow-user-settings/custom-dropdowns) or Field Mapping with your own integration or application fields, you can use [`setDataSources`](/apis/api-reference#setdatasources) to register these data sources with the SDK.

Call `setDataSources` once after enabling headless mode, before rendering any inputs:

```js theme={null}
paragon.setHeadless(true);

paragon.setDataSources({
  dropdowns: {
    my_custom_dropdown: [
      { label: "Option A", value: "a" },
      { label: "Option B", value: "b" },
    ],
  },
  integrationSpecificSources: {
    salesforce: {
      dropdowns: {
        departments: [
          { label: "Engineering", value: "eng" },
          { label: "Sales", value: "sales" },
        ],
      },
    },
  },
});
```

Data sources registered with `setDataSources` are automatically resolved by `getSourcesForInput` and `getFieldOptions`. Integration-specific sources take priority over global sources when the same key is used.

<Card title="SDK Reference" href="/apis/api-reference#setdatasources" horizontal arrow>
  Learn more about `setDataSources()` and its configuration options in the SDK Reference.
</Card>

Once user input is collected, you can save the values back to Paragon using one of the following functions, depending on the input's context:

* [`setPreOptions`](/apis/api-reference#setpreoptions) - Save pre-OAuth options and start the OAuth flow.
* [`setPostOptions`](/apis/api-reference#setpostoptions) - Save post-OAuth options and complete account connection.
* [`updateIntegrationUserSettings`](/apis/api-reference#updateintegrationusersettings) - Save integration-level User Settings.
* [`updateWorkflowUserSettings`](/apis/api-reference#updateworkflowusersettings) - Save workflow-level User Settings.

<Columns cols={2}>
  <Card title="User Settings Example" cta="See code" href="https://github.com/useparagon/connect-headless-example/blob/main/src/components/feature/integration/integration-modal/components/integration-settings.tsx" arrow={false}>
    See our reference implementation of User Settings in the
    example repo.
  </Card>

  <Card title="Input Types Reference" cta="See reference" href="/connect-portal/input-types-reference">
    Learn more about the different Input Types to implement in our reference.
  </Card>
</Columns>

#### Exposing Workflow Configuration

<Frame caption="Optionally, show a list of Workflows for users to enable / disable in the Connect Portal">
  <img src="https://mintcdn.com/paragon/l1vzjNTWrUIk0ls8/assets/headless-workflows.png?fit=max&auto=format&n=l1vzjNTWrUIk0ls8&q=85&s=8f3262e5ea69fb05909121a4b6360088" alt="Workflow Configuration example" width="1656" height="1278" data-path="assets/headless-workflows.png" />
</Frame>

In the Configuration tab of the headful Connect Portal, a list of Workflows appears as a list of toggles that users can opt-in or out of. This is not required if you do not use Workflows are your Workflows are set to be [enabled by default](/connect-portal/displaying-workflows#default-to-enabled).

* To render the list of available Workflows, you can use [`getIntegrationConfig`](/apis/api-reference#getintegrationconfig) and read the `availableWorkflows` key.
* To see what Workflows the user has enabled, you can use [`getUser`](/apis/api-reference#getuser) and read `user.integrations[].configuredWorkflows[].enabled`.
  ```js Getting Workflow state expandable theme={null}
  paragon.getUser();

  // Response:
  {
    "integrations": {
      "slack": {
        // (other properties excluded for brevity)
        "configuredWorkflows": {
          "7b516f0f-2581-470f-a26d-72dfa7b9b554": {
            "enabled": false,
            "settings": {}
          }
        }
      }
    }
  }
  ```
* To toggle a Workflow on or off for a user, you can use [`updateWorkflowState`](/apis/api-reference#updateworkflowstate) to pass a partial update object of the Workflows that should be enabled or disabled for a user.
  ```js Updating Workflow state theme={null}
  paragon.updateWorkflowState({
    // [Workflow UUID]: boolean
    "7b516f0f-2581-470f-a26d-72dfa7b9b554": true,
  });
  ```

<Columns cols={2}>
  <Card title="Workflow Configuration Example" cta="See code" href="https://github.com/useparagon/connect-headless-example/blob/main/src/components/feature/integration/integration-modal/components/workflows.tsx" arrow={false}>
    See our reference implementation of User Settings in the
    example repo.
  </Card>

  <Card title="SDK Reference" cta="See reference" href="/apis/api-reference#updateworkflowstate">
    Learn more about the `updateWorkflowState` method in the SDK Reference.
  </Card>
</Columns>

## Multiple Account Authorization

When implementing the Headless Connect Portal for [Multiple Account Authorization](/apis/api-reference/multi-account-authorization), you'll need to update your UI to handle listing multiple connections for a given integration.

You can use `selectedCredentialId` in the following SDK functions to ensure that the right account is used in multi-account setups:

* [`updateIntegrationUserSettings`](/apis/api-reference#updateintegrationusersettings)
  ```js theme={null}
  paragon.updateIntegrationUserSettings("googledrive", {
    [selectedInput.id]: newValue,
  }, {
    selectedCredentialId: "376910a0-74aa-4e5e-88ab-122a7fb20a56",
  });
  ```

* [`updateWorkflowUserSettings`](/apis/api-reference#updateworkflowusersettings)
  ```js theme={null}
  paragon.updateWorkflowUserSettings("googledrive", selectedWorkflow.id, {
    [selectedInput.id]: newValue,
  }, {
    selectedCredentialId: "376910a0-74aa-4e5e-88ab-122a7fb20a56",
  });
  ```

* [`updateWorkflowState`](/apis/api-reference#updateworkflowstate)
  ```js theme={null}
  paragon.updateWorkflowState({
    "7b516f0f-2581-470f-a26d-72dfa7b9b554": true,
  }, {
    selectedCredentialId: "376910a0-74aa-4e5e-88ab-122a7fb20a56",
  });
  ```

* [`uninstallIntegration`](/apis/api-reference#uninstallintegration)
  ```js theme={null}
  paragon.uninstallIntegration("googledrive", {
    selectedCredentialId: "376910a0-74aa-4e5e-88ab-122a7fb20a56",
  });
  ```

* [`getFieldOptions`](/apis/api-reference#getfieldoptions)
  ```js theme={null}
  paragon.getFieldOptions({
    integration: "googledrive",
    action: "folders",
    selectedCredentialId: "376910a0-74aa-4e5e-88ab-122a7fb20a56",
  });
  ```

In all of the above, you can get the Credential ID for an account from [`getUser()`](/apis/api-reference#getuser), in `user.integrations[].allCredentials[n].id`.

## SDK Reference

The SDK includes the key functions below that should be used when implementing the Headless Connect Portal. Find more details about each function (including parameter types and return values) in the linked reference page.

* [`paragon.getIntegrationMetadata`](/apis/api-reference#getintegrationmetadata): Returns display and branding information for integrations in your project, including a display name and icon.
* [`paragon.installFlow.start`](/apis/api-reference#installflowstart): Prompts the user for third-party authorization details to connect their account. This function should be used when a user expresses intent to install your integration, for example: from a "Connect" button in your integrations catalog.
  * [`paragon.installFlow.setAccountType`](/apis/api-reference#setaccounttype): Sets the account type for an integration being actively installed.
  * [`paragon.installFlow.setPreOptions`](/apis/api-reference#setpreoptions): Sets the pre-OAuth options for an integration being actively installed.
  * [`paragon.installFlow.setPostOptions`](/apis/api-reference#setpostoptions): Sets the post-OAuth options for an integration being actively installed.
* [`paragon.uninstallIntegration`](/apis/api-reference#uninstallintegration): Disconnects the user's account.
* [`paragon.getIntegrationConfig`](/apis/api-reference#getintegrationconfig): Returns the configuration for an integration, including its available User Settings and Workflows.
* [`paragon.getUser`](/apis/api-reference#getuser): Returns the current state of the user, with their integrations and account statuses.
* [`paragon.updateIntegrationUserSettings`](/apis/api-reference#updateintegrationusersettings): Updates integration-level User Settings values.
* [`paragon.updateWorkflowUserSettings`](/apis/api-reference#updateworkflowusersettings): Updates workflow-level User Settings values.
* [`paragon.updateWorkflowState`](/apis/api-reference#updateworkflowstate): Enables or disables Workflows for a user.
* [`paragon.setDataSources`](/apis/api-reference#setdatasources): Registers custom data sources for dropdown and field mapping inputs, globally or per-integration. *(SDK 2.3.0+)*
* [`paragon.getSourcesForInput`](/apis/api-reference#getsourcesforinput): Returns the data sources needed to render a specific input, which can be passed directly to `getFieldOptions`. *(SDK 2.3.0+)*
* [`paragon.getFieldOptions`](/apis/api-reference#getfieldoptions): Returns integration-specific options for dynamic User Settings, such as Dynamic Enum or Field Mapping inputs.
* [`paragon.getDataSourceOptions`](/apis/api-reference#getdatasourceoptions): For compound inputs, returns the configuration for each data source needed to render the input.
