The Genius Scan SDK provides a pre-built scanning interface called ScanFlow that enables you to add document scanning to your app with just a few lines of code. ScanFlow is highly configurable, allowing you to adapt it to your specific needs. This guide will help you get started quickly.
The simple demo projects from our demo repository demonstrate how to configure document scanning.
Before implementing document scanning, you need to install and configure the SDK.
Once you’ve installed and configured the SDK, implement document scanning in just a few lines:
// Create configuration
let configuration = GSKScanFlowConfiguration()
configuration.multiPage = true
configuration.pdfPageSize = .a4
// Start the scan flow
do {
let result = try await GSKScanFlow(configuration: configuration)
.resultByStarting(fromViewController: self)
if let pdfUrl = result.multiPageDocumentURL {
print("PDF saved at: \(pdfUrl)")
} else {
print("No PDF was generated")
}
} catch {
print("Scanning failed: \(error.localizedDescription)")
}
If you cannot use the modern Async/Await API, the SDK also provides closure-based APIs.
// Create configuration
val configuration = ScanFlowConfiguration().apply {
multiPage = true
pdfPageSize = ScanFlowConfiguration.PdfPageSize.A4
}
// Start the scan flow
val scanLauncher = registerForActivityResult(ScanActivity.Contract()) { output ->
when (output) {
is FlowOutput.Success -> {
val pdfFile = output.result.multiPageDocument
Log.d("Scanner", "PDF saved at: ${pdfFile?.absolutePath}")
}
is FlowOutput.Error -> {
Log.e("Scanner", "Scanning failed", output.error)
}
}
}
scanLauncher.launch(configuration)
import { scanWithConfiguration } from "@thegrizzlylabs/web-geniusscan-sdk";
// Configure and launch scanner
try {
const result = await scanWithConfiguration({
multiPage: true,
multiPageFormat: "pdf",
pdfPageSize: "a4",
jpegQuality: 60
});
// Handle the result
const { scans, multiPageDocument } = result;
// Process individual scanned pages
for (const scan of scans) {
const imageBlob = scan.enhancedImage.data;
console.log("Scanned page:", imageBlob);
}
// Process PDF if generated
if (multiPageDocument) {
const pdfBlob = new Blob([multiPageDocument.data],
{ type: multiPageDocument.type });
console.log("PDF generated:", pdfBlob);
}
} catch (error) {
// Handle error or user cancellation
console.error("Scanning failed:", error);
}
import RNGeniusScan from '@thegrizzlylabs/react-native-genius-scan';
// Configure scan flow
try {
// Launch scanner
const result = await RNGeniusScan.scanWithConfiguration({
multiPage: true,
multiPageFormat: 'pdf',
pdfPageSize: 'a4',
jpegQuality: 60
});
// Handle the result
const { multiPageDocumentUrl, scans } = result;
console.log("PDF saved at:", multiPageDocumentUrl);
// Process individual pages
for (const scan of scans) {
console.log("Page:", scan.enhancedUrl);
}
} catch (error) {
// Handle cancellation or error
console.error("Scanning failed:", error);
}
import 'package:flutter_genius_scan/flutter_genius_scan.dart';
// Configure scan flow
var configuration = {
'multiPage': true,
'multiPageFormat': 'pdf',
'pdfPageSize': 'a4',
'jpegQuality': 60,
};
try {
// Launch scanner
var result = await FlutterGeniusScan.scanWithConfiguration(configuration);
// Handle the result
String? pdfUrl = result['multiPageDocumentUrl'];
List<dynamic> scans = result['scans'];
print("PDF saved at: $pdfUrl");
// Process individual pages
for (var scan in scans) {
print("Page: ${scan['enhancedUrl']}");
}
} catch (error) {
// Handle cancellation or error
print("Scanning failed: $error");
}
// Configure scan flow
var configuration = {
multiPage: true,
multiPageFormat: 'PDF',
pdfPageSize: 'A4',
jpegQuality: 60
};
// Launch scanner
cordova.plugins.GeniusScan.scanWithConfiguration(configuration,
// Success callback
function(result) {
var pdfUrl = result.multiPageDocumentUrl;
var scans = result.scans;
console.log("PDF saved at:", pdfUrl);
// Process individual pages
scans.forEach(function(scan) {
console.log("Page:", scan.enhancedUrl);
});
},
// Error callback
function(error) {
console.error("Scanning failed:", error);
}
);
import GeniusScan from '@thegrizzlylabs/capacitor-plugin-genius-scan';
// Configure scan flow
try {
// Launch scanner
const result = await GeniusScan.scanWithConfiguration({
source: 'camera',
multiPage: true,
multiPageFormat: 'pdf',
pdfPageSize: 'a4',
jpegQuality: 60
});
// Handle the result
const { multiPageDocumentUrl, scans } = result;
console.log("PDF saved at:", multiPageDocumentUrl);
// Process individual pages
for (const scan of scans) {
console.log("Page:", scan.enhancedUrl);
}
} catch (error) {
// Handle cancellation or error
console.error("Scanning failed:", error);
}
For .NET MAUI, use the ScanFlowService to start the document scan flow:
using GeniusScanSDK.ScanFlow;
var scanFlowService = new ScanFlowService();
var configuration = new Dictionary<string, object>
{
["source"] = "camera",
["ocrConfiguration"] = new Dictionary<string, object>
{
["languages"] = new[] { "en-US" }
}
};
var result = await scanFlowService.ScanDocument(configuration);
var documentUrl = (string)result["multiPageDocumentUrl"];
The examples above use a minimal scan flow configuration to start scanning and return a document. From there, you can enable additional features such as OCR, barcode extraction, source selection, UI customization, and output controls. The options below show what can be configured on each platform.
ScanFlow configuration controls how the scan flow is presented, what output it generates, and which optional processing is requested. The table below lists actual configuration options and shows where each one is available.
| Configuration option | iOS | Android | Cross-platform | Web |
|---|---|---|---|---|
| Scan source Choose camera, photo library, or provided image input. |
✅ | ✅ | ✅ | - |
| Source image Provide the image to scan when the source is an existing image. |
✅ | ✅ | ✅ | - |
| Multi-page mode Let users capture several pages in one scan flow. |
✅ | ✅ | ✅ | ✅ |
| Multi-page output format Choose the document generated from captured pages. |
✅ | ✅ | ✅ | ✅ |
| PDF page size Set the page size used for generated PDFs. |
✅ | ✅ | ✅ | ✅ |
| PDF max scan dimension Downscale scans before PDF generation. |
✅ | ✅ | ✅ | - |
| PDF text-layer font Use a custom font for searchable PDF text. |
✅ | ✅ | ✅ | - |
| PDF title Set the metadata title for generated PDFs. |
- | - | - | ✅ |
| JPEG quality Control compression quality for captured images. |
✅ | ✅ | ✅ | ✅ |
| Original image output Include the original unprocessed image in the scan result. |
- | - | - | ✅ |
| Skip post-processing screen Return results without showing the review and edit screen. |
✅ | ✅ | ✅ | - |
| Post-processing actions Choose which edit actions users can access. |
✅ | ✅ | ✅ | ✅ |
| Default filter Select the enhancement applied by default. |
✅ | ✅ | ✅ | ✅ |
| Available filters Restrict the filters users can choose from. |
✅ | ✅ | ✅ | ✅ |
| Default curvature correction Apply curvature correction by default. |
✅ | ✅ | ✅ | - |
| Default scan orientation Rotate scans automatically or keep the original orientation. |
✅ | ✅ | ✅ | - |
| Photo library button visibility Hide or show the photo import button. |
✅ | ✅ | ✅ | - |
| Flash button visibility Hide or show the camera flash control. |
✅ | ✅ | ✅ | - |
| Default flash mode Choose flash behavior when capture starts. |
✅ | ✅ | ✅ | - |
| Required readability level Warn users when scans may be blurry or unreadable. |
✅ | ✅ | ✅ | - |
| OCR Run text recognition and choose OCR output formats. |
✅ | ✅ | ✅ | - |
| Structured data extraction Extract receipts, barcodes, or other structured data. |
✅ | ✅ | ✅ | - |
| Barcode types for structured data Limit which barcode symbologies are searched in documents. |
✅ | ✅ | ✅ | - |
| Background color Customize the scan flow background color. |
✅ | ✅ | ✅ | ✅ |
| Foreground color Customize text and icon colors. |
✅ | ✅ | ✅ | ✅ |
| Highlight color Customize detection overlays and accent color. |
✅ | ✅ | ✅ | ✅ |
| Menu color Customize menu styling where supported. |
✅ | - | ✅ | - |
| Localization language Control or inherit the scan flow UI language. |
* | * | * | ✅ |
* Adapts to the platform language. 20 languages are available; see Localization.
Cross-platform covers React Native, Flutter, Cordova, Capacitor, and .NET MAUI. Some options are platform-specific in effect: for example, menu color maps to the iOS ScanFlow menu color, while Android does not expose a native menu color option. The detailed option names and accepted values differ by platform, so use the references below when implementing your configuration.
For allowed values, defaults, and platform-specific behavior, refer to the API and package references:
GSKScanFlowConfiguration - API ReferenceScanFlowConfiguration - API ReferenceThe SDK is localized in 20 of the most commonly used languages.
The features of the SDK will be localized in the device’s active language, except for the Web SDK for which you can specify the language in the configuration with the "language": "fr" key/value.
At this point, you already have a working document scanner. If the default ScanFlow experience covers your use case, you can stop here. When you need more control or additional capabilities, explore these guides:
Start with a free trial license to test the SDK, or contact us directly for a custom quote tailored to your needs.
© 2026 The Grizzly Labs. All rights reserved.