Web

@okyc/web

Open the hosted flow from any website — modal, inline, popup or redirect. Zero dependencies, under 10 KB.

View as Markdown

Version0.2.0

Install

npm install @okyc/web

Your backend creates the session and returns clientToken and url (see sessions). Before embedding, add your site's origin under Settings → Embedding & redirects → Allowed embed origins in the dashboard; the hosted flow refuses to render inside other origins.

Start the flow

Okyc.start(options) opens the flow and returns a Flow with close(), on(event, handler) and the url. This example uses the React wrapper, which calls Okyc.start for you:

main.jsx
function App() {
  const [status, setStatus] = useState('Not verified');
  return (
    <main style={{ fontFamily: 'system-ui', maxWidth: 480, margin: '64px auto' }}>
      <h1>Acme onboarding</h1>
      <p>Status: {status}</p>
      <OkycButton
        // Your backend creates the session and returns { clientToken, sessionUrl }.
        getClientToken={() => fetch('/api/kyc/session', { method: 'POST' }).then((r) => r.json())}
        {...flowHandlers(setStatus)}
      >
        Verify identity
      </OkycButton>
    </main>
  );
}

Handle events

main.jsx
// UX only — the webhook on your backend is the source of truth.
function flowHandlers(setStatus) {
  return {
    onStepStarted: (e) => console.debug('step started', e.step),
    onComplete: (e) => setStatus(`Submitted (${e.status}) — we'll confirm shortly`),
    onExit: () => setStatus('Closed before finishing'),
    onError: (e) => setStatus(`Error: ${e.code}`),
  };
}
CallbackEventPayload
onReadyready—
onStepStartedstep_started{ sessionId, step }
onStepCompletedstep_completed{ sessionId, step }
onCompletecomplete{ sessionId, status } — processing, approved, declined or review
onExitexit{ sessionId, reason } — user_closed or expired
onErrorerror{ code, message } — e.g. token_expired, camera_denied, origin_not_allowed, popup_blocked

flow.on('complete', handler) is the same as the callback. Events are for your UI only: grant access after the webhook.

Options

OptionDefault
clientTokenrequiredst_… from your backend. A secret key is rejected.
sessionUrl / sessionIdone requiredThe session url (its origin and id are used) or the ses_… id.
verifyUrlhttps://verify.okyc.streamHosted flow origin, when you pass sessionId. Must be https except on localhost.
modemodalSee below.
container—Element or selector; required for inline.
locale—Override the flow language.
themeworkflow brandingColour scheme: 'light', 'dark' or 'system'. Brand colour, radius and font come from the workflow branding. (The older { colorScheme } object still works; its primaryColor and radius were never applied.)
ModeBehaviour
modalFull-screen overlay on phones, a centred dialog on desktop in the flow's own card style. Esc or the flow's ✕ closes it (exit with user_closed).
inlineAn iframe in your container; it resizes to the flow's height.
popupA new window; falls back to redirect (and emits popup_blocked) when blocked.
redirectNavigates to the flow; it returns to the session's redirect_url with ?session_id=&status=.

Security

  • The client token goes in the URL fragment (#t=…), which browsers never send to servers.
  • Messages are accepted only from the flow's exact origin and window, with source: "okyc" and v: 1.
  • The iframe gets allow="camera; microphone; fullscreen; clipboard-write" and nothing else.
  • Expired token? Get a new one from your backend (POST /v1/sessions/:id/client_token) and call start again; the flow resumes at the first unfinished step.

On this page