Embeddable iframe SDK for the Uniicy KYC verification flow. No React / Vue peer dependency; vanilla DOM API that you can call from any framework.
npm install @uniicy/kyc-widget
# or
pnpm add @uniicy/kyc-widget
# or
bun add @uniicy/kyc-widget<div id="kyc"></div>
<script type="module">
import { init } from "@uniicy/kyc-widget";
// On your backend you called:
// POST /api/verification/sessions
// Authorization: Bearer sk_live_…
// → { sessionId, clientSecret, hostedUrl, expiresAt }
//
// You pass `sessionId` and `clientSecret` to the SDK on the client.
const uniicy = init({
publishableKey: "pk_live_…",
// Defaults to https://verify.uniicy.com; override for local dev:
// host: "http://localhost:4488",
});
const widget = uniicy.mount(document.getElementById("kyc"), {
sessionId: "…",
clientSecret: "…",
onReady: () => console.log("iframe ready"),
onStep: (s) => console.log("step", s),
onComplete: (r) => console.log("done", r),
onError: (e) => console.error("err", e),
onCancel: () => console.log("user cancelled"),
});
// Tear down when leaving the page:
// widget.destroy();
</script>The package ships full .d.ts files. Import helper types when you need
them in your own code:
import {
init,
type UniicyMessage,
type UniicyCompletePayload,
type UniicyStepPayload,
type UniicyErrorPayload,
} from "@uniicy/kyc-widget";| Event | Payload |
|---|---|
uniicy:ready |
{} |
uniicy:step |
{ step, capturePhase?, reviewStatus? } |
uniicy:complete |
{ sessionId, status, decision? } |
uniicy:error |
{ code, message? } |
uniicy:cancel |
{} — user aborted before reaching completion |
uniicy:resize |
{ height } — SDK grows the iframe automatically |
Every message uses window.postMessage, carries the sessionId, and is
targeted to the parent origin the SDK was mounted on. The SDK validates
both event.origin and sessionId before invoking your callbacks.
- The SDK never mints sessions client-side.
sessionId+clientSecretalways come from a server-to-server call using your secret key (sk_…) — never ship a secret key in the browser. publishableKey(pk_…) is safe for client bundles; it is only used for metadata and billing attribution.- Inbound
postMessageevents are filtered by the host origin you passed toinit({ host })and by the mountedsessionId. - The SDK creates the iframe with
sandbox="allow-scripts allow-same-origin allow-forms allow-popups"andallow="camera; microphone; fullscreen; autoplay; clipboard-read; clipboard-write". - Every published build on npm is signed with npm provenance from GitHub Actions — look for the "Built and signed on GitHub Actions" badge on the package page.
| Tag | Install | When published |
|---|---|---|
latest |
npm i @uniicy/kyc-widget |
When a Changesets "Version Packages" PR merges to main |
canary |
npm i @uniicy/kyc-widget@canary |
On every push to main |
Use canary to test an unreleased fix against your integration; pin
latest for production.
If you'd rather redirect the end-user than embed the flow, skip the SDK
entirely and 302 → the hostedUrl returned at session creation; the
user is redirected back to your returnUrl (with ?session_id=…&status=…
appended) when they finish.
git clone [email protected]:Uniicy/kyc-widget.git
cd kyc-widget
bun install
bun run build
bun run testOpen a PR against main. If your change is user-observable, run
bun run changeset from the repo root and commit the generated file
alongside your patch — see .changeset/README.md.
MIT © Uniicy — see LICENSE.