SDK
Web
KYC SDK

KYC SDK

Lets a customer complete identity verification inside your page. Two ways to use it: we render the screen, or you take only the data layer and build your own interface.

<script src="https://cdn.lunixi.com/lunixi-loader.min.js"></script>
// Renders the whole guided flow into a DOM target
const handle = await Lunixi.kyc.mount('#kyc-container', {
  externalCustomerId: 'cus_8f2a9c',
});
 
// To remove it later
// handle.unmount();

The heavy UI (React plus the flow screens) is downloaded on first mount; before that it is not in your bundle.

How the session is established

On start-up the SDK calls POST /api/v1/kyc/sdk/init and receives a signed session. Every later call uses it.

No secret key is present in the browser. Authentication uses a publishable key plus an Origin match; the browser sets Origin, and code on the page cannot forge it. → Overview

Flow steps

StepMethod
Select jurisdictionsetJurisdiction(code)
Select primary document typesetPrimaryDocumentType(type)
Submit profile fieldssubmitProfileData({ fields })
Record consentsubmitConsent({ consentType, noticeLocale })
Upload a documentuploadDocument({ file, documentType, side, metadata })
Upload liveness videouploadLivenessVideo({ chunkSource, nonceId, challengeSequence })
Submit for verificationsubmitVerification()
Watch the outcomewatchStatus({ onStatusChange })
Request human reviewrequestManualReview({ reasonCode, reasonDetail })

For two-sided documents, front and back are uploaded separately via side.

Environment preflight

Before a session starts you can measure whether the device and surroundings are suitable: light, noise, connection and the granted camera resolution.

const preflight = await Lunixi.kyc.runEnvironmentPreflight({ facingMode: 'user' });
⚠️

This is a measurement, not a gate. The preflight never blocks the flow and releases the camera stream it opens — the server owns the decision. Use the result to show the user a hint like "increase the lighting"; do not rule someone out on your own.

Attach the result to the session with recordEnvironmentPreflight(result), read it back with getEnvironmentPreflight().

Watching status

await client.watchStatus({
  intervalMs: 3000,
  onStatusChange: (status) => render(status),
});

timeoutMs and signal bound how long it runs; terminalStatuses decides which statuses stop it.

Live video verification

When a flow escalates to video verification with a human operator:

TaskMethod
Get access detailsgetLiveVerificationAccess({ forceRefresh })
Join the roomjoinLiveVerification({ deviceFingerprintRef })
Leave the roomleaveLiveVerification({ deviceFingerprintRef })
Open the sessionopenLiveVerificationSession(options)

Configuration

FieldWhat it is for
externalCustomerIdYour own customer reference
linkedObjectType / linkedObjectIdTies the verification to your own record
evidenceContext / evidencePurposeWhy the evidence was collected — written into the audit trail
identitySessionBootstrapUrlIf you want to mint the identity session from your own endpoint
apiBaseUrlTo talk to a base other than the default
allowedOriginThe origin binding of the session token

Things to know

🚫

The SDK is not fail-open. init(), upload and submit calls throw on failure — they never silently return "verified". Wrap them in try/catch and decide for yourself what your flow does when verification cannot complete.

⚠️

The liveness-video endpoints are session-scoped — the real sessionId is baked into the path by the server. If the signed session does not carry those endpoints, uploadLivenessVideo fails closed rather than guessing a URL.

Related