Skip to main content
Sessions required

Every yes:id SDK module needs a valid session before it can run. Complete the Sessions Guide first, it takes 5 minutes and is required before the code below will work.

Using the Liveness SDK

The user starts the check, completes on-screen challenges (blink, look left / right / up / down, look at the camera), and the SDK submits the result to the session.

Create the session on your backend. The browser only receives publishableKey and sessionId.

Prerequisites β€” create a session first​

const [config, session] = await Promise.all([fetch("/config").then(r => r.json()), fetch("/create-session", { method: "POST" }).then(r => r.json())]);

const publishableKey = config.publishableKey; // pk_…
const sessionId = session.sessionId; // vs_…

Enable liveness (and faceMatch if you need matching) when you create the session. See the Sessions Guide.

Web component​

<script type="module">
import { defineYesIdLiveness } from "@yesid/liveness-sdk/component";

defineYesIdLiveness();
</script>

<liveness-check id="liveness" publishable-key="pk_live_xxx" overlay-mode="light" start-label="Start"></liveness-check>

<script>
const el = document.getElementById("liveness");
el.sessionId = sessionId;

el.addEventListener("yesid:success", event => {
console.log(event.detail.response);
console.log(event.detail.submission);
});

el.addEventListener("yesid:failure", event => {
console.error(event.detail.reason, event.detail.message);
});
</script>

You can also assign properties and start the flow yourself:

el.publishableKey = publishableKey;
el.sessionId = sessionId;
await el.start();
el.stop();

If auto-start is not set, the component renders its own start UI.

React​

import { LivenessReact } from "@yesid/liveness-sdk/react";

export function LivenessStep({ publishableKey, sessionId }) {
return (
<LivenessReact
publishableKey={publishableKey}
sessionId={sessionId}
overlayMode="light"
startLabel="Start"
onSuccess={({ response, submission }) => {
console.log(response.status);
console.log(submission.captures.length);
}}
onFailure={event => {
console.error(event.detail.reason, event.detail.message);
}}
/>
);
}

Configuration reference​

OptionTypeRequiredDefaultDescription
publishableKey / publishable-keystringYesβ€”Browser-safe key (pk_…)
sessionId / session-idstringYesβ€”Session created by your backend (vs_…)
autoStart / auto-startbooleanNofalseStart immediately after mount
startLabel / start-labelstringNoStartStart button text
overlayMode / overlay-mode'dark' | 'light'NodarkOverlay theme
challengeLabelsChallengeLabelsNoSDK defaultsOverride challenge copy
overlayLabelsOverlayLabelsNoSDK defaultsOverride overlay copy
className / styleβ€”Noβ€”Passed through to the underlying element

Callbacks (React)​

PropFired whenArgument
onSuccessLiveness passes and results are submitted{ response, submission }
onFailureLiveness, session, or submission failsCustomEvent<LivenessError>
onCaptureA challenge capture is producedCustomEvent<LivenessCapture>
onSessionValidatedSession validation returns validCustomEvent<SessionValidatedEvent>
onSessionInvalidSession is invalid or expiredCustomEvent<SessionInvalidEvent>

Customising labels​

import { LivenessReact } from "@yesid/liveness-sdk/react";

const challengeLabels = {
BLINK: { text: "Blink once", hint: "Close and open both eyes once." },
LOOK_CENTER: { text: "Hold still", hint: "Look straight at the camera." },
};

const overlayLabels = {
start: {
title: "Ready to verify",
hint: "Keep your face inside the oval and follow the instructions.",
button: "Start",
},
permissionDenied: {
title: "Camera blocked",
text: "Allow camera access in your browser settings to continue.",
button: "Retry",
},
};

<LivenessReact publishableKey={publishableKey} sessionId={sessionId} challengeLabels={challengeLabels} overlayLabels={overlayLabels} />;

On the web component, assign the same objects to el.challengeLabels and el.overlayLabels. Defaults are available from @yesid/liveness-sdk as getDefaultChallengeLabels() and getDefaultOverlayLabels().

Theming​

The React wrapper and web component share CSS custom properties:

.brand-liveness {
--yesid-max-width: 440px;
--yesid-aspect-ratio: 4 / 3;
--yesid-video-bg: #f4f7fb;
--yesid-text-color: #0f172a;
--yesid-oval-color: rgba(14, 116, 144, 0.55);
--yesid-oval-detected: rgba(22, 163, 74, 0.9);
--yesid-start-button-bg: linear-gradient(135deg, #0ea5e9, #67e8f9);
--yesid-start-button-color: #082f49;
}
<LivenessReact className="brand-liveness" publishableKey={publishableKey} sessionId={sessionId} />

Complete React example​

This mirrors the yes:id web demo β€” create a session, run liveness, then handle an expired session by creating a new one:

import { useCallback, useEffect, useState } from "react";
import { LivenessReact } from "@yesid/liveness-sdk/react";

export function LivenessScreen() {
const [publishableKey, setPublishableKey] = useState("");
const [sessionId, setSessionId] = useState("");
const [done, setDone] = useState(false);
const [error, setError] = useState("");

const createSession = useCallback(async () => {
setDone(false);
setError("");
try {
const [config, session] = await Promise.all([
fetch("/config").then(r => r.json()),
fetch("/create-session", { method: "POST" }).then(r => r.json()),
]);
setPublishableKey(config.publishableKey);
setSessionId(session.sessionId);
} catch (e) {
setError(e instanceof Error ? e.message : "Failed to create session");
}
}, []);

useEffect(() => {
createSession();
}, [createSession]);

if (!publishableKey || !sessionId) {
return <p>{error || "Creating liveness session…"}</p>;
}

if (done) {
return <p>Liveness complete.</p>;
}

return (
<LivenessReact
publishableKey={publishableKey}
sessionId={sessionId}
overlayMode="light"
startLabel="Start"
onSuccess={() => setDone(true)}
onFailure={event => {
const reason = event.detail?.reason;
if (reason === "CHALLENGE_TIMEOUT" || reason === "CAMERA_PERMISSION_DENIED") {
return;
}
setError(event.detail?.message || "Liveness check failed");
}}
onSessionInvalid={createSession}
/>
);
}
Next

Read the success payload and poll session results for face match: Handling Results β†’