Skip to main content

AnyDocs Quick Start Guide

Get started quickly with multi-page document capture using Veryfi Lens SDK. This guide provides complete step-by-step instructions for integrating AnyDocs — a flexible scanner that captures one or more pages, optionally prompts the user to flip and scan the reverse side, and submits everything together.

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 anydoc-scanner-app -- --template vanilla
cd anydoc-scanner-app

2. Install SDK

npm install veryfi-lens-wasm@latest

3. Copy WASM files

mkdir -p public/wasm
cp -r node_modules/veryfi-lens-wasm/wasm/* public/wasm/

4. 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

5. Create vite.config.js

import { defineConfig } from 'vite';

export default defineConfig({
server: {
headers: {
'Cross-Origin-Embedder-Policy': 'require-corp',
'Cross-Origin-Opener-Policy': 'same-origin',
}
},
optimizeDeps: {
esbuildOptions: {
define: {
global: 'globalThis'
}
}
}
});

6. 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>AnyDoc Scanner</title>
</head>
<body>
<div id="app">
<header>
<h1>AnyDoc Scanner</h1>
</header>

<main>
<div class="scanner-controls">
<button id="scan-anydoc-btn" class="scan-btn">
Scan Document
</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>

7. 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);
}

8. Update src/main.js

import './style.css';
import VeryfiLens from 'veryfi-lens-wasm';

const CLIENT_ID = import.meta.env.VITE_VERYFI_CLIENT_ID;

class AnydocScanner {
constructor() {
this.statusDisplay = document.getElementById('status-display');
this.resultDisplay = document.getElementById('result-display');
this.initializeEventListeners();
}

async initializeScanner() {
try {
await VeryfiLens.init(CLIENT_ID, {
lensFlavor: "anydocs",
torchButton: true,
torchOnStart: false,
blurModal: true,
isDocumentModal: true,
exitButton: true,
anydocMaxPages: 2,
selectedBlueprint: "us_health_insurance_card",
anydocShowFlipMessage: true,
onClose: () => {
console.log("Camera closed");
},
});

this.setupEventHandlers();
this.updateStatus('Scanner initialized');
await VeryfiLens.showCamera(image => {
console.log('Image captured', typeof image === 'string'
? image.substring(0, 100) + '...'
: image);
});
} catch (error) {
this.handleError('Initialization failed', error);
}
}

setupEventHandlers() {
VeryfiLens.onSuccess((result) => {
this.updateStatus('Document 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>Document 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-anydoc-btn').addEventListener('click', () => {
this.initializeScanner();
});
}
}

document.addEventListener('DOMContentLoaded', () => {
new AnydocScanner();
});

9. Run the development server

npm run dev

Open the link provided in terminal (e.g., http://localhost:5173/)

Final Project Structure

/anydoc-scanner-app
├── node_modules/
│ └── veryfi-lens-wasm/
├── public/
│ └── wasm/ # WASM files from SDK
├── src/
│ ├── main.js # AnyDoc scanner logic
│ └── style.css # Styles
├── index.html
├── package.json
├── vite.config.js
└── .env # CLIENT_ID (add to .gitignore)

Configuration Options Explained

The initialization includes several AnyDocs-specific settings:

Basic Settings

  • lensFlavor: "anydocs" - Enables AnyDocs mode
  • selectedBlueprint: "us_health_insurance_card" - Pre-selects a blueprint for data extraction, skipping the blueprint selection modal

Multi-Page Settings

  • anydocMaxPages: 2 - Maximum number of pages allowed per session. Set to null for unlimited pages
  • anydocShowFlipMessage: true - Shows a prompt after each page capture asking the user to flip the document and capture the other side

Display Settings

  • torchButton: true - Shows flashlight toggle
  • torchOnStart: false - Flashlight is off by default when the camera opens
  • exitButton: true - Shows close button
  • blurModal: true - Shows a warning when the captured image is too blurry
  • isDocumentModal: true - Shows a warning when no document is detected in the image

Blueprint Selection

Blueprints define which document template is used for data extraction. You have two options:

Pre-selected Blueprint

Skip the selection modal by specifying the blueprint directly:

{
lensFlavor: "anydocs",
selectedBlueprint: "us_health_insurance_card"
}

Interactive Blueprint Modal

Let users choose from available blueprints at runtime:

{
lensFlavor: "anydocs",
enableBlueprintsModal: true
}

The modal fetches available blueprints from the API and presents them for selection. Listen for selection events via onUpdate:

VeryfiLens.onUpdate((status) => {
if (status.status === 'blueprint_selected') {
console.log('User selected:', status.blueprint);
}
if (status.status === 'blueprint_selection_cancelled') {
console.log('User cancelled blueprint selection');
}
});

AnyDocs Capture Workflows

Fixed Page Count (e.g., Front & Back)

Limit to exactly 2 pages with a flip prompt between captures:

{
lensFlavor: "anydocs",
anydocMaxPages: 2,
anydocShowFlipMessage: true
}

Unlimited Pages

Allow the user to capture as many pages as needed:

{
lensFlavor: "anydocs",
anydocMaxPages: null,
anydocShowFlipMessage: false
}

Multi-Page with Custom Limits

Set a higher page limit with flip prompts:

{
lensFlavor: "anydocs",
anydocMaxPages: 10,
anydocShowFlipMessage: true
}
tip

When anydocMaxPages is reached, the "Add Page" button is hidden and the user can only submit. For single-page submissions the image is sent directly; for multi-page submissions the pages are packaged as a ZIP file automatically.

Customizing Messages

Personalize user-facing text:

await VeryfiLens.init("YOUR_CLIENT_ID", {
lensFlavor: "anydocs",
anydocMaxPages: 10,
anydocShowFlipMessage: true,

// Custom button text
anydocAddPageText: "Capture Next Page",
anydocSubmitText: "Submit All Pages",

// Custom flip prompt
anydocFlipMessageText: "Please flip the document and capture the other side",
anydocFlipContinueText: "Continue",

// Custom modal messages
documentModalMessage: "No document detected. Please position the document in frame",
blurModalMessage: "The image is too blurry. Please hold the camera steady",
submitButtonText: "Submit Anyway",
retakeButtonText: "Retake"
});

Next Steps