GuidesAPI Reference
Log In
Guides

KYC & AML Hosted SDK Integration

Partner Integration Guide

Integrate Wedbush Hosted KYC into your web application with a script tag and a few lines of JavaScript.

Customers can complete identity verification in a secure Wedbush window inside your apps. Your app starts the flow and receives the result — you do not host KYC screens or store Wedbush system credentials.


Before you start

Wedbush will provide:

  1. Partner SDK key — public key used in the browser
  2. SDK script URL — CDN link to wts-partner-sdk.min.js
  3. Allowed website origins — for example, https://app.yourcompany.com; this must match the origin where you load the SDK.

Serve your domain over HTTPS in production.


How it works

  1. A customer fills out account details on your app.
  2. Your app calls WtsPartnerSdk.openKycIframe(...).
  3. A Wedbush KYC window opens for review, status, and documents when needed.
  4. When the customer finishes or closes the window, your onComplete callback runs.
  5. You save externalId and kycStatus, then update your UI.

The Flow:

Your app → Wedbush SDK → KYC window → onComplete → Your app


Step 1 — Add the SDK script

Place this before your application code, for example in index.html:

<script src="https://YOUR_CDN_HOST/wts-partner-sdk.min.js"></script>

This exposes the global object window.WtsPartnerSdk.

Replace YOUR_CDN_HOST with the URL Wedbush gives you.

Staging -> hosted-kyc-assets.staging.wedbush.tech


Step 2 — Start a new KYC application

Collect applicant data in your own forms, then open KYC with that payload. The KYC window shows a read-only review of what you send; it does not replace your data-collection UI.

async function startKyc() {
  if (!window.WtsPartnerSdk) {
    console.error("Wedbush SDK failed to load");
    return;
  }

  await window.WtsPartnerSdk.openKycIframe({
    key: "YOUR_PARTNER_KEY",
    // Use data your application already collected.
    payload: {
      customerType: "person",
      customerData: {
        firstName: "Jane",
        lastName: "Doe",
        emailAddress: "[email protected]",
        documentSsn: "123456789",
        birthdate: "1990-01-15",
        phoneNumber: "+15551234567",
        addresses: [
          {
            type: "legal",
            line1: "123 Main St",
            city: "New York",
            state: "NY",
            postalCode: "10001",
            countryCode: "US",
          },
        ],
      },
    },
    onComplete: (result) => {
      // Persist these values in your backend or session.
      saveApplication({
        externalId: result.externalId,
        kycStatus: result.kycStatus,
        completionStatus: result.status, // completed | closed | error
      });
      updateYourUi(result);
    },
  });
}

Wire it to your button:

<button type="button" onclick="startKyc()">Submit Application</button>

Step 3 — Handle the result

onComplete fields

FieldDescription
externalIdApplication ID — store this to resume later.
kycStatusVerification status from KYC. See the following table.
statusHow the window ended: completed, closed, or error.
messageOptional error message when status is error.

Always save the latest externalId and kycStatus when onComplete runs, including when the customer closes the window.


Step 4 — Resume an existing application

After the first successful start, reopen KYC with the saved ID. The customer skips the review form and lands on the current status or documents screen.

async function resumeKyc(externalId) {
  await window.WtsPartnerSdk.openKycIframe({
    key: "YOUR_PARTNER_KEY",
    externalId,
    onComplete: (result) => {
      saveApplication({
        externalId: result.externalId,
        kycStatus: result.kycStatus,
        completionStatus: result.status,
      });
      updateYourUi(result);
    },
  });
}

API reference — openKycIframe

WtsPartnerSdk.openKycIframe(options): Promise<void>

Options

OptionTypeRequiredDescription
keystringYesYour partner SDK key.
payloadobjectFor new applicationsApplicant data in the perform-KYC-style body.
externalIdstringFor resumingExisting application ID.
onCompletefunctionRecommendedCalled when the KYC window finishes or closes.
environment"local" | "staging" | "production"NoOverrides the environment; it is usually inferred from the script URL.

Pass either payload for a new application or externalId to resume an application. Do not use both as the primary path.

You do not configure Gateway or KYC UI URLs; the SDK includes them.


Framework examples

Vanilla JavaScript

<!DOCTYPE html>
<html>
  <head>
    <title>Open account</title>
    <script src="https://YOUR_CDN_HOST/sdk/wts-partner-sdk.min.js"></script>
  </head>
  <body>
    <button id="start">Submit Application</button>

    <script>
      const PARTNER_KEY = "YOUR_PARTNER_KEY";
      let savedId = localStorage.getItem("kycExternalId") || "";
      let savedStatus = localStorage.getItem("kycStatus") || "";

      document.getElementById("start").onclick = async () => {
        const options = {
          key: PARTNER_KEY,
          onComplete: (result) => {
            if (result.externalId) {
              savedId = result.externalId;
              localStorage.setItem("kycExternalId", result.externalId);
            }

            if (result.kycStatus) {
              savedStatus = result.kycStatus;
              localStorage.setItem("kycStatus", result.kycStatus);
            }

            alert("KYC: " + savedStatus);
          },
        };

        if (savedId) {
          options.externalId = savedId;
        } else {
          options.payload = {
            customerType: "person",
            customerData: {
              firstName: "Jane",
              lastName: "Doe",
              emailAddress: "[email protected]",
            },
          };
        }

        await WtsPartnerSdk.openKycIframe(options);
      };
    </script>
  </body>
</html>

React

async function startKyc({ partnerKey, payload, externalId, onDone }) {
  const sdk = window.WtsPartnerSdk;

  if (!sdk) {
    throw new Error("Wedbush SDK not loaded");
  }

  await sdk.openKycIframe({
    key: partnerKey,
    payload: externalId ? undefined : payload,
    externalId: externalId || undefined,
    onComplete: onDone,
  });
}

// Example button handler.
async function onClickSubmit() {
  await startKyc({
    partnerKey: process.env.REACT_APP_WTS_PARTNER_KEY,
    payload: buildPayloadFromForm(),
    onDone: (result) => {
      setExternalId(result.externalId);
      setKycStatus(result.kycStatus);
    },
  });
}

Load the script in public/index.html or your host HTML, not through npm.

Angular

async startKyc(): Promise<void> {
  const sdk = window.WtsPartnerSdk;

  if (!sdk) {
    this.error = "Wedbush SDK failed to load";
    return;
  }

  await sdk.openKycIframe({
    key: this.partnerKey,
    payload: this.externalId ? undefined : this.buildPayload(),
    externalId: this.externalId || undefined,
    onComplete: (result) => {
      if (result.externalId) {
        this.externalId = result.externalId;
      }

      this.kycStatus = result.kycStatus;
    },
  });
}

Add a TypeScript declaration if needed:

interface WtsCompleteResult {
  externalId: string;
  kycStatus: string;
  status: "completed" | "closed" | "error";
  message?: string;
}

interface Window {
  WtsPartnerSdk?: {
    openKycIframe: (options: {
      key: string;
      payload?: Record<string, unknown>;
      externalId?: string;
      environment?: "local" | "staging" | "production";
      onComplete?: (result: WtsCompleteResult) => void;
    }) => Promise<void>;
  };
}

Customer experience (what they see)

StepWhat happens
ReviewThe customer confirms the details your app sent (read-only).
StatusShows verification status, can refresh, and may allow document uploads.
DocumentsIf required: passport front only; license or national ID front and back.
Done / CloseThe result returns to your onComplete callback.

Closing the window (×) still returns the latest status, so your buttons stay accurate.


Checklist for go-live

  • Receive the partner key from Wedbush.
  • Allowlist production origin(s), including the exact scheme and host, for example https://app.example.com.
  • Add the SDK script URL to your pages.
  • Test the new-application path with payload.
  • Test the resume path with externalId.
  • Persist externalId and kycStatus in onComplete.
  • Verify that the UI shows Approved, Denied, and Under Review correctly.
  • Serve the site over HTTPS.

Troubleshooting

IssueWhat to check
WtsPartnerSdk is undefinedCheck the script URL, load order, and ad blockers.
Origin not allowedConfirm that Wedbush allowlisted the exact origin, including https://.
Launch or session errors after refreshLaunch codes are one-time. Call openKycIframe again from your button.
Button still says Submit after KYCSave the onComplete result and drive the UI from the stored status.
Resume shows Review againPass externalId only; do not send a new payload.

Support

Contact your Wedbush partner manager or integration support for:

  • Partner keys for staging and production
  • Origin allowlist updates
  • The SDK script URL for your environment

Did this page help you?