scanforge
v1.1.0
Published
Official Node.js SDK for the scan-forge OCR service
Maintainers
Readme
scanforge
Official Node.js SDK for the scan-forge OCR service — an on-premise, AI-powered drop-in replacement for ABBYY Recognition Server.
Installation
npm install scanforgeRequires Node.js 18+ (uses built-in fetch and FormData).
Quick Start
import { ScanForge } from 'scanforge';
const client = new ScanForge({ apiKey: 'sf_live_...' });
// Extract text from a PDF
const result = await client.ocr('faktura.pdf');
console.log(result.text);
// Detect barcodes
const barcodes = await client.barcodes('dokument.pdf');
barcodes.forEach(b => console.log(b.value, b.type));
// Convert a scan to DOCX
await client.convert('skan.png', { output: 'wynik.docx' });API Reference
new ScanForge(config)
Creates a new client instance.
| Parameter | Type | Required | Default |
|---|---|---|---|
| config.apiKey | string | Yes | — |
| config.baseUrl | string | No | https://api.scanforge.tech |
const client = new ScanForge({
apiKey: 'sf_live_...',
baseUrl: 'https://ocr.your-server.com', // for self-hosted deployments
});client.ocr(filePath, options?)
Extracts text from a PDF or image file. The call submits an asynchronous OCR job on the server and transparently polls until it finishes, then resolves with the result — you don't need to manage the job lifecycle yourself.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| filePath | string | — | Path to input file (PDF, PNG, JPG, TIFF) |
| options.language | string | 'pol' | OCR language code |
| options.pageNumber | number | — | Process a single page (0-indexed) |
| options.pageRange | string | — | 1-indexed, inclusive page selector: '3' or '1-5'. Takes precedence over pageNumber. Omit for the whole document. |
| options.separatePages | boolean | false | Return per-page output |
| options.pollIntervalMs | number | 1500 | How often to poll the job while waiting |
| options.timeoutMs | number | 600000 | Overall timeout (10 min) before throwing |
Returns Promise<OcrResult>
interface OcrResult {
text: string;
pages: number;
metadata: Record<string, unknown>;
}Example
const result = await client.ocr('invoice.pdf', { language: 'eng' });
console.log(result.text); // extracted text
console.log(result.pages); // number of pages processed
// Only OCR pages 1 through 5:
const partial = await client.ocr('long.pdf', { pageRange: '1-5' });Low-level async API
ocr() and convert() are convenience wrappers over the async job API. If you
want to submit a job and poll for it yourself (e.g. to show progress, or to hand
polling off to a queue), use the low-level methods directly.
client.submitOcr(filePath, options?)
Uploads the file and submits an async OCR job, returning immediately. Accepts the
same options as ocr() (language, pageNumber, pageRange, separatePages).
Returns Promise<{ jobId: string; status: 'queued' | 'running' | 'succeeded' | 'failed' }>
client.getOcrJob(jobId)
Fetches the current state of a job.
Returns Promise<OcrJob>
interface OcrJob {
jobId: string;
status: 'queued' | 'running' | 'succeeded' | 'failed';
createdAt?: string;
updatedAt?: string;
result?: OcrSyncResponse; // present only when status === 'succeeded'
error?: string; // present only when status === 'failed'
}Example
const { jobId } = await client.submitOcr('invoice.pdf', { pageRange: '1-5' });
let job = await client.getOcrJob(jobId);
while (job.status === 'queued' || job.status === 'running') {
await new Promise((r) => setTimeout(r, 1500));
job = await client.getOcrJob(jobId);
}
if (job.status === 'failed') throw new Error(job.error);
console.log(job.result.text);client.barcodes(filePath, options?)
Detects and decodes barcodes (1D and 2D) in a document.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| filePath | string | — | Path to input file |
| options.pageNumber | number | 0 | Page to scan (0 = all pages) |
Returns Promise<BarcodeResult[]>
interface BarcodeResult {
value: string; // decoded barcode content
type: string; // symbology e.g. 'EAN-13', 'QR-Code', 'CODE-128'
page: number; // 1-indexed page number
}Example
const barcodes = await client.barcodes('shipment.pdf');
for (const b of barcodes) {
console.log(b.value, b.type, b.page);
}client.convert(filePath, options)
Converts a PDF or image to an editable document format (DOCX or XLSX). The output format is determined by the file extension of options.output. Like ocr(), this runs as an asynchronous server job that the client polls to completion before writing the file.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| filePath | string | — | Path to input file |
| options.output | string | — | Destination path (.docx or .xlsx) |
| options.language | string | 'pol' | OCR language code |
| options.pageRange | string | — | 1-indexed, inclusive page selector: '3' or '1-5' |
| options.pollIntervalMs | number | 1500 | How often to poll the job while waiting |
| options.timeoutMs | number | 600000 | Overall timeout (10 min) before throwing |
Returns Promise<void> — writes the converted file to options.output.
Example
// Convert to Word document
await client.convert('scan.pdf', { output: 'result.docx' });
// Convert to Excel spreadsheet (preserves table structure)
await client.convert('table.pdf', { output: 'data.xlsx' });Error Handling
All methods throw ScanForgeError on failure.
import { ScanForge, ScanForgeError } from 'scanforge';
const client = new ScanForge({ apiKey: 'sf_live_...' });
try {
const result = await client.ocr('document.pdf');
} catch (err) {
if (err instanceof ScanForgeError) {
console.error(err.message); // human-readable message
console.error(err.status); // HTTP status code (if applicable)
console.error(err.body); // raw response body from the server
}
}| Error condition | status |
|---|---|
| Invalid API key | 401 |
| Unsupported file type | 422 |
| Server error | 5xx |
| Network / connection failure | undefined |
Configuration
Self-hosted deployment
Point the client at your own scan-forge server:
const client = new ScanForge({
apiKey: 'sf_live_...',
baseUrl: 'https://ocr.internal.example.com',
});Environment variables (recommended)
Keep secrets out of your source code:
const client = new ScanForge({
apiKey: process.env.SCANFORGE_API_KEY,
baseUrl: process.env.SCANFORGE_URL, // optional
});Requirements
- Node.js 18+ — uses native
fetch,FormData, andBlob - A running scan-forge server — see scan-forge deployment docs
License
MIT © Moonforge
