Get started with WebSDK integration

Integrate with the Sumsub WebSDK.

To get started with the WebSDK integration:

  1. Generate an access token to be passed to the WebSDK during initialization.
  2. Install an NPM package or use the CDN version of the script. We also have a package for React.
  3. Launch the WebSDK initialization function with the accessToken parameter you have generated at the first step, as shown in the standalone example.
  4. Conduct verification and handle results.

📘

Note

To initialize the WebSDK within the mobile app using WebView, make sure that:

  • WebView is able to access device local storage and initialize the camera. For older iOS versions, the camera can be accessed only from the Safari browser or WebView SFSafariViewController.
  • HTML5 video playback is allowed (we are using some instructions within <video> tags). If the video instructions are not played, try using WebChromeClient to enable video playback.
  • Autoplay in fullscreen mode is disabled and allowsInlineMediaPlayback is set to true for WebView with running SDK.
  • The selector file is implemented on your side (required for file uploads).

Generate SDK access token

To generate an access token, use this API method as the following example demonstrates:

curl -X POST \
  'https://api.sumsub.com/resources/accessTokens?userId=JamesBond007&levelName=basic-kyc-level&ttlInSecs=600' \
  -H 'Accept: application/json'
{
  "token": "eyJhbGciOiJub25lIn0.eyJqdGkiOiJfYWN0LTZmODI2ZTU0LTE2MzctNDViMS05NzMyLWY1MjZiN2YxNWE3YyIsInVybCI6Imh0dHBzOi8vYXBpLnN1bXN1Yi5jb20ifQ.",
  "userId": "JamesBond007"
}

📘

Note

  • Provide a unique and meaningful userId parameter, which can be an external user ID in your system or an email address. If your userId or levelName contains reserved characters (e.g., @, +, white spaces as %20), they should be URL-encoded, otherwise you may get a signature mismatch or just an invalid parameter value.
  • When generating an access token for Local Data Processing, use the regional domain. For example, api.uae.sumsub.com. Further processing will be carried out in the region, which is guaranteed by our SDKs.
  • Authenticate all API requests as described in this article.
  • For testing purposes, use an app token and secret key pair created in Sandbox mode to request authorization headers.
  • Make sure your integration code does not validate or analyze the access token content, as the format is not fixed and may undergo changes. The token must be treated as an arbitrary string with the maximum length of 1KB.
  • An access token for the applicant has limited access to the API, e.g., it is only valid for 1 applicant and cannot access other applicants. If you reuse access tokens, set up an access token expiration handler.

Set up frontend integration

To integrate the WebSDK:

  1. Install the NPM package.
npm i @sumsub/websdk --save
yarn add @sumsub/websdk
  1. Import the snsWebSdk module.
import snsWebSdk from '@sumsub/websdk';

Alternatively, use the standalone package.

<script src = "https://static.sumsub.com/idensic/static/sns-websdk-builder.js"></script>
  1. Create a container for the WebSDK on your page.
<!-- iframe will be inserted as a child element -->
<div id="sumsub-websdk-container"></div>
  1. Initialize the WebSDK.
/**
 * @param accessToken - access token that you generated on the backend
 * @param applicantEmail - applicant email (not required)
 * @param applicantPhone - applicant phone (not required)
 * @param customI18nMessages - customized locale messages for current session (not required)
 */
function launchWebSdk(accessToken, applicantEmail, applicantPhone, customI18nMessages) {
    let snsWebSdkInstance = snsWebSdk
        .init(
            accessToken,
            // token update callback, must return Promise
            // Access token expired
            // get a new one and pass it to the callback to re-initiate the WebSDK
            () => this.getNewAccessToken()
        )
        .withConf({
            lang: "en", //language of WebSDK texts and comments (ISO 639-1 format)
            email: applicantEmail,
            phone: applicantPhone,
            theme: "dark" | "light",
        })
        .withOptions({ addViewportTag: false, adaptIframeHeight: true })
        // see below what kind of messages WebSDK generates
        .on("idCheck.onStepCompleted", (payload) => {
            console.log("onStepCompleted", payload);
        })
        .on("idCheck.onError", (error) => {
            console.log("onError", error);
        })
        .build();

    // you are ready to go:
    // just launch the WebSDK by providing the container element for it
    snsWebSdkInstance.launch("#sumsub-websdk-container");
}

function getNewAccessToken() {
    return Promise.resolve(newAccessToken); // get a new token from your backend
}
/**
 * @param accessToken - access token that you generated on the backend
 * @param applicantEmail - applicant email (not required)
 * @param applicantPhone - applicant phone (not required)
 * @param customI18nMessages - customized locale messages for current session (not required)
 */
function launchWebSdk(accessToken, applicantEmail, applicantPhone, customI18nMessages) {
    let snsWebSdkInstance = snsWebSdk
        .init(
            accessToken,
            // token update callback, must return Promise
            // Access token expired
            // get a new one and pass it to the callback to re-initiate the WebSDK
            () => this.getNewAccessToken()
        )
        .withConf({
            lang: "en", //language of WebSDK texts and comments (ISO 639-1 format)
            email: applicantEmail,
            phone: applicantPhone,
            i18n: customI18nMessages, //JSON of custom SDK Translations
            uiConf: {
                customCss: "https://url.com/styles.css",
                // URL to css file in case you need change it dynamically from the code
                // the similar setting at Customizations tab will rewrite customCss
                // you may also use to pass string with plain styles `customCssStr:`
            },
        })
        .withOptions({ addViewportTag: false, adaptIframeHeight: true })
        // see below what kind of messages WebSDK generates
        .on("idCheck.stepCompleted", (payload) => {
            console.log("stepCompleted", payload);
        })
        .on("idCheck.onError", (error) => {
            console.log("onError", error);
        })
        .build();

    // you are ready to go:
    // just launch the WebSDK by providing the container element for it
    snsWebSdkInstance.launch("#sumsub-websdk-container");
}

function getNewAccessToken() {
    return Promise.resolve(newAccessToken); // get a new token from your backend
}

📘

Note

  • Make sure that accessToken was provided to the SDK initialization function.
  • SDK's iframe resizes itself according to its container and SDK screen content, so the container itself shouldn't have a static size, but should adjust to the screen size. Try to use the <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> tags.

ATTRIBUTES OF withConf PARAMETER

Name Type Required Description Default

lang

String

No

The language (ISO 639-1) in which the WebSDK texts and comments should be displayed.

en

translationName

String

No

Overrides the level translation value for a specific SDK run.

N/A

customizationName

String

No

Overrides the level customization value for a specific SDK run.

N/A

country

String

No

Alpha-3 country code to prefill it on the document upload screen.

N/A

email

String

No

User email to propagate it to the applicant.

N/A

phone

String

No

User phone number to propagate it to the applicant.

N/A

theme

dark or light

No

Sets a light or dark theme. Set 'dark'|'light' to match your website current theme. By default, with no theme attribute, the theme is automatically selected and follows the user device theme.

N/A

documentDefinitions

Object

No

Pre-filled definitions on the doCapture screen.

N/A

autoSelectDocumentDefinitions

Boolean

No

Whether we should automatically select a document provided in documentDefinitions. If true, the Doc Type Selector screen will be skipped.

N/A

controlledNavigationBack

Boolean

No

Whether we allow to control the navigation of the SDK from the host application side. If true, then you can navigate back to the previous screen by calling navigateBack().

N/A

enableScrollIntoView

Boolean

No

Controls the scrolling function within and outside of the SDK page.

  • true — SDK page is scrolled up to the top any time an applicant changes pages inside the SDK. Your website page is scrolled up as well.
  • false — SDK page stays at the same position no matter if an applicant changes pages inside the SDK or not. Your website page is not scrolled as well.

true

STRUCTURE OF documentDefinitions PARAMETER

The documentDefinitions parameter is a key-value object, where keys are idDocSetType and values are documentDefinition.

Possible values of idDocSetType are:

Value Description

IDENTITY

Identity document step.

IDENTITY2

Second identity document step.

IDENTITY3

Third identity document step.

IDENTITY4

Fourth identity document step.

Possible attributes of documentDefinition are:

Name Type Required Description

country

String

Yes

Alpha-3 country code.

idDocType

String

Yes

Document type.

ATTRIBUTES OF withOptions PARAMETER

Name Type Required Description Default

addViewportTag

Boolean

No

Adds the viewport metatag for iFrame for mobile-optimized SDK adjustments.

true

adaptIframeHeight

Boolean

No

Allows our SDK to adapt its height, depending on the size of the frame/container/page/screen.

true

ATTRIBUTES OF withConf PARAMETER

Name Type Required Description Default

lang

String

No

The language (ISO 639-1) in which the WebSDK texts and comments should be displayed.

en

country

String

No

Alpha-3 country code to prefill it on the document upload screen.

N/A

email

String

No

User email to propagate it to the applicant.

N/A

phone

String

No

User phone number to propagate it to the applicant.

N/A

i18n

JSON

No

Custom SDK translations to change dynamically on the SDK initialization.

N/A

uiConf

Object

No

SDK custom configuration.

N/A

documentDefinitions

Object

No

Pre-filled definitions on the doCapture screen.

N/A

ATTRIBUTES OF uiConf PARAMETER

Name Type Required Description Default

customCss

String

No

URL to your external CSS file for SDK to use during initialization.

N/A

customCssStr

String

No

Plain string with changes in CSS.

N/A

scrollIntoView

Boolean

No

Disables/enables automatic scrolling on SDK screen switches.

true

STRUCTURE OF documentDefinitions PARAMETER

The documentDefinitions parameter is a key-value object, where keys are idDocSetType and values are documentDefinition.

Possible values of idDocSetType are:

Value Description

IDENTITY

Identity document step.

IDENTITY2

Second identity document step.

IDENTITY3

Third identity document step.

IDENTITY4

Fourth identity document step.

Possible attributes of documentDefinition are:

Name Type Required Description

country

String

Yes

Alpha-3 country code.

idDocType

String

Yes

Document type.

ATTRIBUTES OF withOptions PARAMETER

Name Type Required Description Default

addViewportTag

Boolean

No

Adds the viewport metatag for iFrame for mobile-optimized SDK adjustments.

true

adaptIframeHeight

Boolean

No

Allows our SDK to adapt its height, depending on the size of the frame/container/page/screen.

true

React integration

To integrate with React:

  1. Install websdk-react.
import SumsubWebSdk from '@sumsub/websdk-react'
  1. Initialize the WebSDK.
<SumsubWebSdk
  accessToken={accessToken}
  expirationHandler={accessTokenExpirationHandler}
  config={config}
  options={options}
  onMessage={messageHandler}
  onError={errorHandler}
/>

📘

Note

Use a newly generated accessToken for initialization and prepare an expiration handler.

Standalone example of WebSDK initialization

The following is a fully working example; — change the $ACCESS_TOKEN variable with the appropriate value, save it to an HTML file, and open in your browser.

<html>
    <head>
        <title>WebSDK CDN Example</title>
    </head>
    <body>
        <script src="https://static.sumsub.com/idensic/static/sns-websdk-builder.js"></script>
        <div id="sumsub-websdk-container"></div>
    </body>
</html>

<script>
function launchWebSdk(accessToken, applicantEmail, applicantPhone) {
    let snsWebSdkInstance = snsWebSdk
        .init(accessToken, () => this.getNewAccessToken())
        .withConf({
            lang: "en",
            email: applicantEmail,
            phone: applicantPhone,
        })
        .withOptions({ addViewportTag: false, adaptIframeHeight: true })
        .on("idCheck.onStepCompleted", (payload) => {
            console.log("onStepCompleted", payload);
        })
        .on("idCheck.onError", (error) => {
            console.log("onError", error);
        })
        .onMessage((type, payload) => {
            console.log("onMessage", type, payload);
        })
        .build();
    snsWebSdkInstance.launch("#sumsub-websdk-container");
}

// Requests a new access token from the backend side.
function getNewAccessToken() {
    return Promise.resolve($NEW_ACCESS_TOKEN);
}

launchWebSdk($ACCESS_TOKEN);
</script>
<html>
    <head>
        <title>WebSDK CDN Example</title>
    </head>
    <body>
        <script src="https://static.sumsub.com/idensic/static/sns-websdk-builder.js"></script>
        <div id="sumsub-websdk-container"></div>
    </body>
</html>

<script>
function launchWebSdk(accessToken, applicantEmail, applicantPhone) {
    let snsWebSdkInstance = snsWebSdk
        .init(accessToken, () => this.getNewAccessToken())
        .withConf({
            lang: "en",
            email: applicantEmail,
            phone: applicantPhone,
            i18n: { document: { subTitles: { IDENTITY: "Upload a document that proves your identity" } } },
            onMessage: (type, payload) => {
                console.log("WebSDK onMessage", type, payload);
            },
            uiConf: {
                customCssStr:
                    ":root {\n  --black: #000000;\n   --grey: #F5F5F5;\n  --grey-darker: #B2B2B2;\n  --border-color: #DBDBDB;\n}\n\np {\n  color: var(--black);\n  font-size: 16px;\n  line-height: 24px;\n}\n\nsection {\n  margin: 40px auto;\n}\n\ninput {\n  color: var(--black);\n  font-weight: 600;\n  outline: none;\n}\n\nsection.content {\n  background-color: var(--grey);\n  color: var(--black);\n  padding: 40px 40px 16px;\n  box-shadow: none;\n  border-radius: 6px;\n}\n\nbutton.submit,\nbutton.back {\n  text-transform: capitalize;\n  border-radius: 6px;\n  height: 48px;\n  padding: 0 30px;\n  font-size: 16px;\n  background-image: none !important;\n  transform: none !important;\n  box-shadow: none !important;\n  transition: all 0.2s linear;\n}\n\nbutton.submit {\n  min-width: 132px;\n  background: none;\n  background-color: var(--black);\n}\n\n.round-icon {\n  background-color: var(--black) !important;\n  background-image: none !important;\n}",
            },
            onError: (error) => {
                console.error("WebSDK onError", error);
            },
        })
        .withOptions({ addViewportTag: false, adaptIframeHeight: true })
        .on("idCheck.stepCompleted", (payload) => {
            console.log("stepCompleted", payload);
        })
        .on("idCheck.onError", (error) => {
            console.log("onError", error);
        })
        .onMessage((type, payload) => {
            console.log("onMessage", type, payload);
        })
        .build();
    snsWebSdkInstance.launch("#sumsub-websdk-container");
}

// Requests a new access token from the backend side.
function getNewAccessToken() {
    return Promise.resolve($NEW_ACCESS_TOKEN);
}

launchWebSdk($ACCESS_TOKEN);
</script>