Skip to main content

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.

info

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

  1. Create an account at Veryfi Portal
  2. Contact Veryfi's sales/support team to request SDK access
  3. 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

danger

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) mode
  • selectedBlueprint: "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 bottle
  • prescriptionLabelWidthRatio: 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 outline
  • prescriptionLabelSquareWidthRatio: 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 toggle
  • torchOnStart: false - Flashlight is off by default when the camera opens
  • exitButton: 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.

  1. The camera opens with the bottle outline overlay
  2. The user taps the capture button to start recording
  3. A red "REC" indicator appears at the top while recording
  4. The user slowly rotates the bottle so the entire label passes through the overlay
  5. The user taps the capture button again to stop recording
  6. A video preview appears with Retake video and Submit buttons
  7. On submit, the video is packaged into a ZIP file and sent to the Veryfi API
tip

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