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 Document Capture SDK
The widget validates the session, lets the user capture or upload the document, extracts the card, submits images to yes:id, and returns OCR on yesid:success.
Create the session on your backend. The browser only receives publishableKey and sessionId.
Prerequisites β create a session firstβ
Your backend calls the yes:id Session API with the secret key, then the frontend initializes the widget:
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_β¦
See the Sessions Guide for the backend request body, including documentCapture.allowedDocuments and sourceMode.
Web componentβ
<script type="module">
import { defineYesIdDocumentCapture } from '@yesid/document-scanner';
defineYesIdDocumentCapture();
</script>
<yesid-document-capture
id="document-scanner"
publishable-key="pk_live_xxx"
></yesid-document-capture>
<script>
const scanner = document.getElementById('document-scanner');
scanner.sessionId = sessionId; // set after /create-session returns
scanner.addEventListener('yesid:success', (event) => {
const { response, submission } = event.detail;
console.log(response);
console.log(submission.images);
});
scanner.addEventListener('yesid:failure', (event) => {
console.error(event.detail.message);
});
</script>
You can also set credentials as element properties:
scanner.publishableKey = publishableKey;
scanner.sessionId = sessionId;
Reactβ
import { DocumentCapture } from '@yesid/document-scanner/react';
export function DocumentScanStep({ publishableKey, sessionId }) {
return (
<DocumentCapture
publishableKey={publishableKey}
sessionId={sessionId}
onSuccess={({ response, submission }) => {
console.log(response);
console.log(submission.images);
}}
onFailure={({ message }) => {
console.error(message);
}}
/>
);
}
Configuration referenceβ
| Option | Type | Required | Description |
|---|---|---|---|
publishableKey / publishable-key | string | Yes | Browser-safe key (pk_β¦) |
sessionId / session-id | string | Yes | Session created by your backend (vs_β¦) |
selectedDocument | { type, country } | No | Pin a document when the session allows more than one type |
disabled | boolean | No | Disable interaction (for example until the user picks a document type) |
cameraFacingMode | 'environment' | 'user' | No | Preferred camera. Default 'environment' |
cameraGuideEnabled | boolean | No | Show the capture guide overlay |
cameraGuidePreset | 'id-card' | 'a4' | 'custom' | No | Guide and detection preset |
labels | ScannerLabels | No | Override UI copy |
Capture mode (single vs front + back) and camera/upload availability come from the session (sourceMode, allowedDocuments, requiredSides). You do not set those as widget attributes.
Selecting a document typeβ
yesid:session-validated returns the documents allowed for this session. If more than one type is allowed, set selectedDocument before capture:
scanner.addEventListener('yesid:session-validated', (event) => {
const allowed = event.detail?.documentCapture?.allowedDocuments ?? [];
if (allowed.length === 1) {
scanner.selectedDocument = {
type: allowed[0].type,
country: allowed[0].country,
};
}
});
// After the user picks from your own dropdown:
scanner.selectedDocument = { type: 'national_id', country: 'TZ' };
React equivalent: pass selectedDocument={{ type: 'national_id', country: 'TZ' }}.
Customising labelsβ
Omit a key to keep the SDK default. Set a value to "" to hide that label.
scanner.labels = {
sourcePicker: {
titleBoth: 'Capture your document',
hint: 'Make sure the entire document is clearly visible.',
cameraButton: 'Camera',
uploadButton: 'Upload',
},
permission: {
title: 'Camera permission required',
text: 'We need access to your camera to capture your document.',
button: 'Allow Camera',
},
};
Complete React exampleβ
This mirrors the integration in the yes:id web demo β create a session, render the scanner, handle OCR on success:
import { useCallback, useEffect, useState } from 'react';
import { DocumentCapture } from '@yesid/document-scanner/react';
export function DocumentScanScreen() {
const [publishableKey, setPublishableKey] = useState('');
const [sessionId, setSessionId] = useState('');
const [error, setError] = useState('');
const createSession = useCallback(async () => {
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 (error) {
return (
<button type="button" onClick={createSession}>
Retry session
</button>
);
}
if (!publishableKey || !sessionId) {
return <p>Creating verification sessionβ¦</p>;
}
return (
<DocumentCapture
key={sessionId}
publishableKey={publishableKey}
sessionId={sessionId}
onSuccess={({ response, submission }) => {
const ocr = response?.resultData?.ocr ?? response?.ocr;
const portrait = ocr?.portrait;
const fields = ocr?.documentData ?? [];
}}
onFailure={({ message }) => setError(message)}
onSessionInvalid={() => createSession()}
/>
);
}
Listen for capture events and read OCR fields: Handling Results β