Prescription Label Quick Start Guide
Get started quickly with prescription label video capture using Veryfi Lens SDK. This guide provides complete step-by-step instructions for integrating the Prescription Label flavor — a video-based scanner with a bottle-shaped overlay guide that records the user rotating a pill bottle, packages the video into a ZIP, and submits it for data extraction.
Prerequisites:
- Node.js (latest LTS version recommended)
- CLIENT ID from the Keys section in Settings of your account
- Lens For Browser enabled for your account (confirm with Customer Support)
Authorization
- Create an account at Veryfi Portal
- Contact Veryfi's sales/support team to request SDK access
- Once approved, obtain your Client ID from the Keys section in Settings
Project Setup
1. Create Project
In current directory:
npm create vite@latest . -- --template vanilla
Or in a new directory:
npm create vite@latest prescription-label-app -- --template vanilla
cd prescription-label-app
2. Install SDK
npm install veryfi-lens-wasm@latest
3. Store Client ID in .env file
Make sure to add .env file to .gitignore to avoid committing it to the repository.
VITE_VERYFI_CLIENT_ID=your_client_id_here
4. Update index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Prescription Label Scanner</title>
</head>
<body>
<div id="app">
<header>
<h1>Prescription Label Scanner</h1>
</header>
<main>
<div class="scanner-controls">
<button id="scan-prescription-btn" class="scan-btn">
Scan Prescription Label
</button>
</div>
<div id="status-display" class="status-display"></div>
<div id="result-display" class="result-display"></div>
</main>
</div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
5. Update src/style.css
:root {
--primary-color: #4CAF50;
--hover-color: #45a049;
--error-color: #ff4444;
--text-color: #333;
--background-color: #f5f5f5;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
background-color: var(--background-color);
}
#app {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
header {
text-align: center;
margin-bottom: 2rem;
}
.scanner-controls {
display: flex;
justify-content: center;
margin-bottom: 2rem;
}
.scan-btn {
padding: 1rem 2rem;
font-size: 1rem;
border: none;
border-radius: 4px;
background-color: var(--primary-color);
color: white;
cursor: pointer;
transition: background-color 0.3s ease;
}
.scan-btn:hover {
background-color: var(--hover-color);
}
.status-display {
margin-bottom: 1rem;
padding: 1rem;
border-radius: 4px;
background-color: white;
min-height: 2rem;
}
.result-display {
padding: 1rem;
border-radius: 4px;
background-color: white;
overflow-x: auto;
}
.error {
color: var(--error-color);
}
6. Update src/main.js
import './style.css';
import VeryfiLens from 'veryfi-lens-wasm';
const CLIENT_ID = import.meta.env.VITE_VERYFI_CLIENT_ID;
class PrescriptionLabelScanner {
constructor() {
this.statusDisplay = document.getElementById('status-display');
this.resultDisplay = document.getElementById('result-display');
this.initializeEventListeners();
}
async initializeScanner() {
try {
await VeryfiLens.init(CLIENT_ID, {
lensFlavor: "prescription_label",
torchButton: true,
torchOnStart: false,
exitButton: true,
prescriptionLabelShowOverlay: true,
onClose: () => {
console.log("Camera closed");
},
});
this.setupEventHandlers();
this.updateStatus('Scanner initialized');
await VeryfiLens.showCamera(video => {
console.log('Video captured', video);
});
} catch (error) {
this.handleError('Initialization failed', error);
}
}
setupEventHandlers() {
VeryfiLens.onSuccess((result) => {
this.updateStatus('Prescription label processed successfully');
this.displayResult(result);
});
VeryfiLens.onFailure((error) => {
this.handleError('Processing failed', error);
});
VeryfiLens.onUpdate((status) => {
this.updateStatus(`Status: ${status.status}`);
});
}
updateStatus(message) {
this.statusDisplay.textContent = message;
}
displayResult(result) {
this.resultDisplay.innerHTML = `
<h3>Prescription Label Data:</h3>
<pre>${JSON.stringify(result, null, 2)}</pre>
`;
}
handleError(context, error) {
console.error(`${context}:`, error);
this.statusDisplay.innerHTML = `
<div class="error">
${context}: ${error.message}
</div>
`;
}
initializeEventListeners() {
document.getElementById('scan-prescription-btn').addEventListener('click', () => {
this.initializeScanner();
});
}
}
document.addEventListener('DOMContentLoaded', () => {
new PrescriptionLabelScanner();
});
7. Run the development server
npm run dev
Open the link provided in terminal (e.g., http://localhost:5173/)
Final Project Structure
/prescription-label-app
├── node_modules/
│ └── veryfi-lens-wasm/
├── src/
│ ├── main.js # Prescription label scanner logic
│ └── style.css # Styles
├── index.html
├── package.json
└── .env # CLIENT_ID (add to .gitignore)
Configuration Options Explained
The initialization includes several Prescription Label–specific settings:
Basic Settings
lensFlavor: "prescription_label"- Enables the Prescription Label (video) modeselectedBlueprint: "prescription_medication_label"- Pre-selects the blueprint used for data extraction. This is also the default when no blueprint is provided
Overlay Settings
prescriptionLabelShowOverlay: true- Shows the bottle-shaped cutout overlay that guides the user where to position the pill bottleprescriptionLabelWidthRatio: 0.55- Width of the bottle overlay (0–1 relative to viewport)prescriptionLabelHeightRatio: 0.65- Height of the bottle overlay (0–1 relative to viewport)prescriptionLabelText: "Position prescription label in outline"- Instructional text shown to the user
Optional Square Overlay
prescriptionLabelShowSquareOverlay: false- Shows a square/rectangular overlay guide instead of (or in addition to) the bottle outlineprescriptionLabelSquareWidthRatio: 0.8- Square overlay width (0–1 relative to viewport)prescriptionLabelSquareHeightRatio: 0.5- Square overlay height (0–1 relative to viewport)
Display Settings
torchButton: true- Shows flashlight toggletorchOnStart: false- Flashlight is off by default when the camera opensexitButton: true- Shows close button
Capture Workflow
The Prescription Label flavor records video instead of capturing still images. This is ideal for cylindrical pill bottles where the label wraps around the container.
- The camera opens with the bottle outline overlay
- The user taps the capture button to start recording
- A red "REC" indicator appears at the top while recording
- The user slowly rotates the bottle so the entire label passes through the overlay
- The user taps the capture button again to stop recording
- A video preview appears with Retake video and Submit buttons
- On submit, the video is packaged into a ZIP file and sent to the Veryfi API
The capture button toggles recording — first tap starts, second tap stops. Listen for recording_started and recording_stopped events via onUpdate to react to recording state changes.
Recording Lifecycle Events
Listen to recording and processing events through onUpdate:
VeryfiLens.onUpdate((status) => {
switch (status.status) {
case 'recording_started':
console.log('Recording started');
break;
case 'recording_stopped':
console.log('Recording stopped');
break;
case 'capture_started':
console.log('Preparing video for submission');
break;
case 'processing_started':
console.log('Zipping video');
break;
case 'processing_completed':
console.log('Video zipped, ready to upload');
break;
case 'capture_completed':
console.log('Submission complete');
break;
case 'capture_failed':
console.log('Capture failed');
break;
}
});
Customizing the Overlay
Bottle Outline Only (default)
{
lensFlavor: "prescription_label",
prescriptionLabelShowOverlay: true,
prescriptionLabelWidthRatio: 0.55,
prescriptionLabelHeightRatio: 0.65,
prescriptionLabelText: "Position prescription label in outline"
}
Square/Rectangular Overlay
Use a rectangular guide instead of the bottle outline:
{
lensFlavor: "prescription_label",
prescriptionLabelShowOverlay: false,
prescriptionLabelShowSquareOverlay: true,
prescriptionLabelSquareWidthRatio: 0.8,
prescriptionLabelSquareHeightRatio: 0.5
}
No Overlay
Hide both overlays for a clean camera view:
{
lensFlavor: "prescription_label",
prescriptionLabelShowOverlay: false,
prescriptionLabelShowSquareOverlay: false
}
Custom Submit Handler
If you need to handle the recorded video yourself instead of letting the SDK upload it, set a customSubmitHandler. It receives the base64-encoded ZIP that contains the video file:
await VeryfiLens.init("YOUR_CLIENT_ID", {
lensFlavor: "prescription_label",
customSubmitHandler: (zipBase64) => {
console.log('Got video ZIP (base64), size:', zipBase64.length);
}
});
Next Steps
- Configuration Options - Explore all available settings
- UI Customization - Style the prescription label scanner with CSS
- Event Handling - Learn about all available events