# Check-Driven Integration

## Overview

This guide walks you through integrating the Web SDK with ComplyCube using the check-driven approach, giving you direct control over individual verification steps.

{% hint style="info" %}
For a quick copy-paste example, use our [integration assistant](https://portal.complycube.com/developers).
{% endhint %}

{% hint style="warning" %}
You’re viewing the **check-driven** SDK guide - an approach that provides detailed control but is best suited for **partners** or **advanced use cases.**  We recommend using **workflow integration** for most implementations.
{% endhint %}

## Integration flow

The Web SDK runs as part of your frontend but relies on your backend to create **secure tokens**. Here’s how it works:

{% stepper %}
{% step %}

#### **Create a client**

Register a new **client** (i.e. customer) using the ComplyCube API
{% endstep %}

{% step %}

#### **Generate an SDK token**

Your backend requests a **JWT token** tied to that client.
{% endstep %}

{% step %}

#### **Import and mount the SDK**

Add the JS and CSS files, then mount the SDK in your web app.
{% endstep %}

{% step %}

#### Capture documents, videos, and selfies

The SDK guides your customer through the required steps.
{% endstep %}

{% step %}

#### Perform verification checks

Captured data is securely sent to ComplyCube for verification checks, and results are delivered in real time through the API or webhooks.
{% endstep %}
{% endstepper %}

![Web SDK Integration Flow](https://648014528-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Flv7UhJvTbxeq4s3KwQpn%2Fuploads%2FK0Q5uDXRom50YsDvvkYZ%2Fdocumentation_web_sdk_flow.png?alt=media\&token=9154ae1c-2b2e-4b65-907f-d9b40c39700e)

## Integration guide

{% stepper %}
{% step %}

#### Create a client

Every verification flow starts with a **client** (i.e. customer). Use the API to [create the client](https://app.gitbook.com/s/kAhgmUKSf8CFUFVL3GEe/core-resources/clients/create-a-client).

**Example request**

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST https://api.complycube.com/v1/clients \
     -H 'Authorization: <YOUR_API_KEY>' \
     -H 'Content-Type: application/json' \
     -d '{
          "type": "person",
          "email": "john.doe@example.com",
          "personDetails":{
               "firstName": "John",
               "lastName" :"Doe"
          }
        }'
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
const { ComplyCube } = require("@complycube/api");

const complycube = new ComplyCube({ apiKey: "<YOUR_API_KEY>" });

const client = await complycube.client.create({
  type: "person",
  email: "john.doe@example.com",
  personDetails: {
    firstName: "John",
    lastName: "Doe"
  }
});
```

{% endtab %}

{% tab title="Python" %}

```python
from complycube import ComplyCubeClient
cc_api = ComplyCubeClient(api_key='<YOUR_API_KEY>')

new_client = {
    'type':'person',
    'email':'john.doe@example.com',
    'personDetails': {
        'firstName':'John',
        'lastName':'Doe'
    }
}

client = cc_api.clients.create(**new_client)
```

{% endtab %}

{% tab title="PHP" %}

```php
use ComplyCube\ComplyCubeClient;

$ccapi = new ComplyCubeClient('<YOUR_API_KEY>');

$result = $ccapi->clients()->create([
    'type' => 'person',
    'email' => 'john@doe.com',
    'personDetails' => [
        'firstName' => 'John',
        'lastName' => 'Doe'
    ]
]);
```

{% endtab %}

{% tab title=".NET" %}

```csharp
using ComplyCube.Net;
using ComplyCube.Net.Resources.Clients;

var clientApi = new ClientApi(new ComplyCubeClient("<YOUR_API_KEY>"));
var newClient = new ClientRequest {
  type = "person",
  email = "john@doe.com",
  personDetails = new PersonDetails {
    firstName = "John",
    lastName = "Doe"
  }
}

var client = await clientApi.CreateAsync(newclientRequest);
```

{% endtab %}
{% endtabs %}

**Example response**

The response will contain an `id` (the Client ID). It is required for the next step.

```javascript
{
    "id": "5eb04fcd0f3e360008035eb1",
    "type": "person",
    "email": "john.doe@example.com",
    "personDetails": {
        "firstName": "John",
        "lastName": "Doe",
    },
    "createdAt": "2020-01-04T17:24:29.146Z",
    "updatedAt": "2020-01-04T17:24:29.146Z"
}
```

{% hint style="info" %}
See [Clients API Reference](https://app.gitbook.com/s/kAhgmUKSf8CFUFVL3GEe/core-resources/clients) to learn more.
{% endhint %}
{% endstep %}

{% step %}

#### Generate an SDK token

Your backend must create an **SDK token** for each new flow. This token links the SDK session to the client. Tokens are short-lived and must not be reused.

**Example request**

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST https://api.complycube.com/v1/tokens \
     -H 'Authorization: <YOUR_API_KEY>' \
     -H 'Content-Type: application/json' \
     -d '{
          "clientId":"CLIENT_ID",
          "referrer": "https://www.example.com/*"
        }'
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
const { ComplyCube } = require("@complycube/api");

const complycube = new ComplyCube({ apiKey: "<YOUR_API_KEY>" });

const token = await complycube.token.generate("CLIENT_ID", {
    referrer: "https://www.example.com/*"
});
```

{% endtab %}

{% tab title="Python" %}

```python
from complycube import ComplyCubeClient

cc_api = ComplyCubeClient(api_key='<YOUR_API_KEY>')

token = cc_api.tokens.create('CLIENT_ID','https://www.example.com/*')
```

{% endtab %}

{% tab title="PHP" %}

```php
 use ComplyCube\ComplyCubeClient;

$ccapi = new ComplyCubeClient('<YOUR_API_KEY>');

$report = $ccapi->tokens()->generate('CLIENT_ID', 'https://www.example.com/*');
```

{% endtab %}

{% tab title=".NET" %}

```csharp
using ComplyCube.Net;
using ComplyCube.Net.Resources.SDKTokens;

var sdkTokenApi = new SDKTokenApi(new ComplyCubeClient("<YOUR_API_KEY>"));

var sdkTokenRequest = {
  clientId = "CLIENT_ID",
  referrer = "https://www.example.com/*"
}

var sdkToken = await sdkTokenApi.GenerateToken(sdkTokenRequest);
```

{% endtab %}
{% endtabs %}

**Example response**

```javascript
{
    "token": "<CLIENT_TOKEN>"
}
```

{% hint style="info" %}
See [SDK Token API Reference](https://app.gitbook.com/s/kAhgmUKSf8CFUFVL3GEe/other-resources/tokens) to learn more.
{% endhint %}
{% endstep %}

{% step %}

#### Import the SDK

To import our Web SDK,  you need to include it in your target page HTML:

```html
<!DOCTYPE html>
<html>
  <head>
    ...
    <!-- Importing the Javascript library -->
    <script src="complycube.min.js"></script>

    <!-- Importing the default CSS -->
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
     <!-- This is where the Web SDK will be mounted -->
    <div id="complycube-mount"></div>
  </body>
</html>

```

<details>

<summary><strong>Loading the SDK with Integrity</strong> <em>(Optional)</em></summary>

For additional security, you can optionally load the ComplyCube Web SDK using **Subresource Integrity (SRI)**. This allows the browser to verify that the JavaScript and CSS files have not been modified by validating them against cryptographic checksums.

#### **Retrieve the latest SDK integrity values**

To ensure you always use the latest supported SDK version and integrity hashes, retrieve the asset metadata from the Web SDK info endpoint.

**Example request**

```bash
curl -X POST https://api.complycube.com/v1/webSdk/latest \
     -H 'Authorization: <YOUR_API_KEY>'
```

**Example response**

The response includes the URLs and corresponding integrity values for both the JavaScript and CSS assets.

{% code overflow="wrap" %}

```json
{
  "js": {
    "url": "<JAVASCRIPT_ASSET_URL>/complycube.min.js",
    "integrity": "sha384-<INTEGRITY_HASH_1> sha384-<INTEGRITY_HASH_2>"
  },
  "css": {
    "url": "<CSS_ASSET_URL>/style.css",
    "integrity": "sha384-<INTEGRITY_HASH_1> sha384-<INTEGRITY_HASH_2>"
  }
}
```

{% endcode %}

#### **Import the SDK using integrity attributes**

Use the returned values to load the SDK in your HTML with `integrity` and `crossorigin` attributes:

```html
<!DOCTYPE html>
<html>
  ...
  <head>
    <!-- Importing the Javascript library -->
    <script
      src="<JAVASCRIPT_ASSET_URL>/sdk.min.js"
      integrity="sha384-<INTEGRITY_HASH_1> sha384-<INTEGRITY_HASH_2>"
      crossorigin="anonymous">
    </script>

    <!-- Importing the default CSS -->
    <link
      rel="stylesheet"
      href="<CSS_ASSET_URL>/style.css"
      integrity="sha384-<INTEGRITY_HASH_1> sha384-<INTEGRITY_HASH_2>"
      crossorigin="anonymous">
  </link>
  </head>
  
  <!-- This is where the Web SDK will be mounted -->
  <body>
    <div id="complycube-mount"></div>
  </body>
</html>
```

{% hint style="info" %}

#### Notes

* Using SRI is ***optional***, but recommended for environments with stricter security requirements.
* The crossorigin="anonymous" attribute is required when using SRI with assets served from a different origin.
* Integrity values may change when the SDK is updated. Always retrieve the latest values from the endpoint.
  {% endhint %}

</details>

{% hint style="info" %}
The links to `complycube.min.js` and `style.css` can be found in your [developers portal](https://portal.complycube.com/developers/webSdk).
{% endhint %}
{% endstep %}

{% step %}

#### Mount the SDK

With the generated SDK token, the Web SDK can be initialised in your frontend using the following Javascript code:

```javascript
ComplyCube.mount({
  token: '<YOUR_WEB_SDK_TOKEN>',
  containerId: 'complycube-mount',
  stages: [
    'intro',
    'documentCapture',
    {
      name: 'faceCapture',
      options: {
        mode: 'video'
      }
    },
    'completion'
  ],
  onComplete: function(data) {
    // Using the data attributes returned, request your
    // backend server to perform the necessary ComplyCube checks
    console.info('Capture complete');
  },
  onModalClose: function() {
    // Handle the modal closure attempt
  },
  onError: function ({ type, message }) {
    if (type === 'token_expired') {
      // Request a new SDK token
    } else {
      // Handle other errors
      console.err(message);
    }
  }
});
```

{% hint style="info" %}
The SDK mount parameters are described in the [SDK settings](#settings) section below.
{% endhint %}

{% hint style="info" %}

#### Referrer policy

To enable successful communication between the SDK and our servers, your web page's **Referrer Policy** header should be set to `strict-origin-when-cross-origin`. This ensures that the referrer information is securely transmitted during HTTP requests.

You can either do it programmatically or add it directly to the web page as follows:\
`<meta name="referrer" content="strict-origin-when-cross-origin">`
{% endhint %}
{% endstep %}

{% step %}

#### Perform checks

Using the `data` returned by the SDK, via the `onComplete` callback, you can now instruct your backend server to run the appropriate checks using the [create a check endpoint](https://docs.complycube.com/api-reference/checks/create-a-check).

For instance, use:

* `documentCapture.documentId` to run a [document check](https://docs.complycube.com/api-reference/check-types/document-check).
* `documentCapture.documentId` and `faceCapture.livePhotoId` to run an[ identity check](https://docs.complycube.com/api-reference/check-types/identity-check).
* `documentCapture.documentId` and `faceCapture.liveVideoId`  to run an [enhanced identity check](https://docs.complycube.com/api-reference/check-types/enhanced-identity-check).
* `poaCapture.documentId` to run a [proof of address check](https://docs.complycube.com/api-reference/check-types/proof-of-address-check).

If you have [set up webhooks ](https://docs.complycube.com/api-reference/other-resources/webhooks/create-a-webhook)as described in our [webhooks guide](https://docs.complycube.com/documentation/guides/webhooks),  you will be notified once a check completes.

To retrieve the check results, you can perform a get [check request](https://app.gitbook.com/s/kAhgmUKSf8CFUFVL3GEe/core-resources/checks/create-a-check).&#x20;

**Example request**

{% tabs %}
{% tab title="cURL" %}

```javascript
curl -X GET https://api.complycube.com/v1/checks/{:checkId} \
     -H 'Authorization: <YOUR_API_KEY>' 
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
const { ComplyCube } = require("@complycube/api");

const complycube = new ComplyCube({ apiKey: "<YOUR_API_KEY>" });

const check = await complycube.check.get("CHECK_ID");
```

{% endtab %}

{% tab title="Python" %}

```python
from complycube import ComplyCubeClient

cc_api = ComplyCubeClient(api_key='<YOUR_API_KEY>')

check = cc_api.checks.get('CHECK_ID')
```

{% endtab %}

{% tab title="PHP" %}

```php
use ComplyCube\ComplyCubeClient;

$ccapi = new ComplyCubeClient('<YOUR_API_KEY>');

$check = $ccapi->checks()->get('CHECK_ID');
```

{% endtab %}

{% tab title=".NET" %}

```csharp
using ComplyCube.Net;
using ComplyCube.Net.Resources.Checks;

var checkApi = new CheckApi(new ComplyCubeClient("<YOUR_API_KEY>"));

var check = await checkApi.GetAsync("CHECK_ID");
```

{% endtab %}
{% endtabs %}
{% endstep %}
{% endstepper %}

## SDK reference

This section describes all configurable settings, callbacks, lifecycle methods, and branding options available in the ComplyCube Web SDK.

### Settings

<table><thead><tr><th width="218.09765625">Option</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td>The SDK token generated by your backend. This is <strong>required</strong>.<br><br><strong>Type</strong>: <code>string</code></td></tr><tr><td><code>containerId</code></td><td><p>The ID of the container element where the SDK mounts. This must be an empty element.</p><p></p><p><strong>Type:</strong> <code>string</code><br><strong>Default value</strong>: <code>complycube-mount</code></p></td></tr><tr><td><code>useModal</code></td><td>This defines whether the UI screens load into a modal instead of inline.<br><br><strong>Type:</strong> <code>boolean</code><br><strong>Default value</strong>: <code>true</code></td></tr><tr><td><code>disableClientAnalytics</code></td><td><p>This defines whether we track client analytics or not.<br></p><p><strong>Type:</strong> <code>boolean</code><br><strong>Default value</strong>: <code>false</code></p></td></tr><tr><td><code>stages</code></td><td><p>This is the list of stages your clients will go through. Stages can be provided as strings or as objects. See <a href="#stages">Stages</a> below to learn more.<br></p><p><strong>Type:</strong> <code>array[object]</code> or <code>array[string]</code></p><p><strong>Default values</strong>: <code>['intro', 'faceCapture, 'documentCapture', 'completion']</code></p></td></tr><tr><td><code>language</code></td><td><p>The UI language. Valid values include:<br></p><p><code>en</code> , <code>ar</code>, <code>br</code>, <code>de</code>, <code>es</code>, <code>fr</code>, <code>hi</code>, <code>hk</code>, <code>id</code>, <code>it</code>, <code>ja</code>, <code>ko</code>, <code>nl</code>, <code>no</code>, <code>pl</code>, <code>pt</code>, <code>sv</code>, <code>th</code>, <code>vi</code>, <code>zh</code> <br></p><p><strong>Type:</strong> <code>string</code><br><strong>Default value</strong>: <code>en</code></p></td></tr></tbody></table>

### Callback

Callbacks let you respond to SDK lifecycle events.

<table><thead><tr><th width="218.0234375">Option</th><th>Description</th></tr></thead><tbody><tr><td><code>onComplete</code></td><td><p>Triggered after the client completes the verification flow. Typically used to trigger a check on your backend.<br></p><p>Depending on the stages provided, <code>data</code> may include the following attributes:<br></p><ul><li><p><code>documentCapture</code></p><ul><li><code>documentId</code>:  ID of the captured document.</li><li><code>documentType:</code> Type of document uploaded.</li></ul></li><li><p><code>faceCapture</code></p><ul><li><code>liveVideoId</code>: ID of the captured video. <strong>OR</strong>;</li><li><code>livePhotoId</code>: ID of the captired photo.</li></ul></li><li><p><code>poaCapture</code></p><ul><li><code>documentId</code>: ID of the uploaded proof of address document.</li><li><code>documentType</code>: Type of the uploaded proof of address document.</li></ul></li></ul></td></tr><tr><td><code>onError</code></td><td><p>Triggered when an error occurs. The error object has two attributes:</p><p></p><ul><li><p><code>type</code>: This can be:</p><ul><li><code>exception</code> </li><li><code>token_expired</code> : indicates the token has expired. When this occurs, a new <strong>SDK token must be provided</strong>.</li></ul></li><li><code>message</code>: Description of the error.</li></ul></td></tr><tr><td><code>onExit</code></td><td>This callback is triggered when your client exits before completing the flow. It will return the exit reason, e.g., <code>USER_CONSENT_NOT_GRANTED</code>.</td></tr><tr><td><code>onModalClose</code></td><td>Triggered when the client tries to close the modal. You can allow or prevent closure by updating the <code>isModalOpen</code> attribute using <a href="#updating-settings">updateSettings</a>.</td></tr></tbody></table>

### Updating settings

A number of settings can be updated at runtime as follows:

```javascript
complycube = ComplyCube.mount({...});

// Replace the SDK token
complycube.updateSettings({ token: "NEW_SDK_TOKEN" });
...
// Open the modal
complycube.updateSettings({ isModalOpen: true });

//Close the modal
complycube.updateSettings({ isModalOpen: false });

```

### Unmounting the SDK

If you are using the SDK in a Single Page Application (SPA), you can call the unmount function to remove the SDK and reset its state.

```javascript
complycube = ComplyCube.mount({...});
...
complycube.unmount()
```

## Stages

The `stages` array defines the verification flow. Each stage can be passed as a **string** or as an **object** with options.

#### Supported stage names

* `intro`: Welcome screen.
* `userConsentCapture`: Capture customer consent.
* `documentCapture`: Capture ID documents.
* `faceCapture`: Capture selfies or liveness videos.
* `poaCapture`: Capture proof of address document.
* `completion`: End of flow.

{% hint style="info" %}
When `userConsentCapture` is enabled, always handle the `onExit` callback if the client declines consent.
{% endhint %}

{% hint style="info" %}
Please make sure you pass the [`clientConsent`](https://docs.complycube.com/api-reference/checks) parameter when consent is granted by your client.
{% endhint %}

When a stage is passed as **object**, it will have two attributes, `name` and `options`.

### Name

This is the [stage name](#supported-stage-names)

### Options

This allows you to customize each stage as follows:

<table><thead><tr><th width="171.09765625">Stage Name</th><th>Options</th></tr></thead><tbody><tr><td><code>intro</code></td><td><ul><li><code>heading</code>: Change the intro screen heading.</li><li><code>message</code>: A list of messages to display on the intro screen. Max size <strong>3</strong>.</li><li><code>startButtonText</code>: Change the text of the start button on the intro screen.</li></ul></td></tr><tr><td><code>documentCapture</code></td><td><ul><li><code>crossDeviceOnly</code>:  A boolean that indicates whether to force users to capture their document using their phone. This removes the document upload option.</li><li><p><code>documentTypes</code>: The list of ID document types visible to the user. Valid document types include:</p><ul><li><code>passport</code></li><li><code>driving_license</code></li><li><code>national_identity_card</code></li><li><code>residence_permit</code></li></ul><p><br>Each value can be either a <strong>boolean</strong> or a <strong>country object</strong>. A boolean toggles the visibility of the document type, while a country object specifies the issuing country for non-passport documents, bypassing the country selection screen. The country value is the <a href="https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">two-letter country ISO code</a>.</p></li></ul></td></tr><tr><td><code>faceCapture</code></td><td><ul><li><code>mode</code>: The mode of the facial capture. Possible values are: <code>photo</code> or <code>video</code>.</li></ul></td></tr><tr><td><code>poaCapture</code></td><td><ul><li><p><code>documentTypes</code>: The list of Proof of Address (POA) document types visible to the client. Valid POA document types include:</p><ul><li><code>bank_statement</code></li><li><code>utility_bill</code></li></ul></li></ul><p>The value of each document type is a boolean that toggles the visibility of the document type. </p></td></tr><tr><td><code>completion</code></td><td><ul><li><code>heading</code>: Change the completion screen heading.</li><li><code>message</code>:  A message to display on the completion screen. Max size <strong>1</strong>.</li></ul></td></tr></tbody></table>

#### Example options object

```javascript
stages: [
  {
    name: "intro",
    options: {
      heading: "We need to verify your identity",
      message: [
        "In order to open an account, we need to check a few things.",
        "This will take only a moment",
      ],
      startButtonText: "Start Verification"
    },
  },
  "userConsentCapture",
  {
    name: "documentCapture",
    options: {
      crossDeviceOnly: true,
      documentTypes: {
        passport: true,
        driving_license: false,
        national_identity_card: true,
        residence_permit: {
          country: "GB",
        },
      },
    },
  },
  {
    name: "faceCapture",
    options: {
      mode: "video"
    },
  },
  {
    name: "poaCapture",
    options: {
      documentTypes: {
        bank_statement: true,
        utility_bill: false,
      },
    },
  },
  {
    name: "completion",
    options: {
      heading: "Thank you for completing the process",
      message: ["we will get in touch shortly"]
    },
  }
];

```

## Branding

You can customise the SDK’s look and feel with the `branding` object. It comprises of the attributes outlined below.

### Appearance

The `appearance` object allows you to customize the color scheme of the SDK with CSS values (e.g. RGBA, Hex). Customizable attributes include:

<table><thead><tr><th width="314.77779343108637">Attribute</th><th>Description</th></tr></thead><tbody><tr><td><code>infoPopupColor</code></td><td>Warning popup background color.</td></tr><tr><td><code>infoPopupTextColor</code></td><td>Warning popup background color.</td></tr><tr><td><code>infoPopupLinkHoverColor</code></td><td>Warning popup fallback Link on hover background color.</td></tr><tr><td><code>infoPopupLinkActiveColor</code></td><td>Warning popup fallback Link active background color.</td></tr><tr><td><code>errorPopupColor</code></td><td>Error popup background color.</td></tr><tr><td><code>errorPopupTextColor</code></td><td>Error popup text color.</td></tr><tr><td><code>errorPopupLinkHoverColor</code></td><td>Error popup fallback Link on hover background color.</td></tr><tr><td><code>errorPopupLinkActiveColor</code></td><td>Error popup fallback Link active background color.</td></tr><tr><td><code>cameraButtonHoverColor</code></td><td>Camera button on hover background color.</td></tr><tr><td><code>cameraButtonActiveColor</code></td><td>Camera button active background color.</td></tr><tr><td><code>iconButtonActiveColor</code></td><td>Icon button active background color.</td></tr><tr><td><code>iconButtonHoverColor</code></td><td>Icon button on hover background color.</td></tr><tr><td><code>primaryButtonColor</code></td><td>Primary button background color.</td></tr><tr><td><code>primaryButtonTextColor</code></td><td>Primary button text color.</td></tr><tr><td><code>primaryButtonActiveColor</code></td><td>Primary button active background color.</td></tr><tr><td><code>primaryButtonHoverColor</code></td><td>Primary button on hover background color.</td></tr><tr><td><code>primaryButtonBorderColor</code></td><td>Primary button border color.</td></tr><tr><td><code>secondaryButtonColor</code></td><td>Secondary button background color.</td></tr><tr><td><code>secondaryButtonTextColor</code></td><td>Secondary button text color.</td></tr><tr><td><code>secondaryButtonActiveColor</code></td><td>Secondary button active background color.</td></tr><tr><td><code>secondaryButtonHoverColor</code></td><td>Secondary button on hover background color.</td></tr><tr><td><code>secondaryButtonBorderColor</code></td><td>Secondary button border color.</td></tr><tr><td><code>documentSelectorColor</code></td><td>Document selector background color.</td></tr><tr><td><code>documentSelectorTextColor</code></td><td>Document selector text color.</td></tr><tr><td><code>documentSelectorActiveBorderColor</code></td><td>Document selector active background color.</td></tr><tr><td><code>documentSelectorHoverBorderColor</code></td><td>Document selector on the hover background color.</td></tr><tr><td><code>linkHoverColor</code></td><td>Link on the hover background color.</td></tr><tr><td><code>linkActiveColor</code></td><td>Link active background color.</td></tr><tr><td><code>linkUnderlineColor</code></td><td>Link underline color.</td></tr><tr><td><code>linkHoverTextColor</code></td><td>Link on the hover text color.</td></tr><tr><td><code>bodyTextColor</code></td><td>SDK content text color.</td></tr><tr><td><code>headingTextColor</code></td><td>SDK heading text color.</td></tr><tr><td><code>subheadingTextColor</code></td><td>SDK subheading text color.</td></tr></tbody></table>

### Logo

The `logo` object has the following attributes:

* `lightLogoUrl`: URL for your logo's light version.
* `darkLogoUrl`:  URL for your logo's dark version.

#### Example of logo branding

```javascript
branding: {
  appearance: {
    primaryButtonColor: '#FF0000',
  },
  logo: {
    lightLogoUrl: 'light_logo_url',
    darkLogoUrl: 'dark_logo_url',
  }
},
```

### Text Brand

The `textBrand` attribute represents the textual format of your brand.

#### Example of text branding

```javascript
branding: {
  appearance: {
    primaryButtonColor: '#FF0000',
  },
  textBrand: 'Acme Bank'
}
```

{% hint style="info" %}
If `logo` and `textBrand` attributes are specified at the same time, `logo` takes precedence.
{% endhint %}
