Quick start

DQ Scanner lets your web page capture documents from the user's scanner. Add one script, drop in your license key, and call scan() — each page comes back as an image (or a single PDF). The user installs the small DQ Scanner service once on their Windows machine.

<script src="http://scanner.daleelteq.cloud/sdk/daleelteq-scanner.js"></script>
<script>
  const scanner = await DQScanner.create({ licenseKey: "YOUR_KEY" });
  const devices = await scanner.getScanners();
  const pdf = await scanner.scan({ source: devices[0], format: "pdf" });
  // upload `pdf` (a Blob) wherever you like
</script>

1 · Add the SDK

Include the script from your DQ Scanner host:

<script src="http://scanner.daleelteq.cloud/sdk/daleelteq-scanner.js"></script>

2 · Your license key

Use the key issued for your domain. Keep it in your page or app config.

const LICENSE_KEY = "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...";

3 · Scan

const scanner = await DQScanner.create({ licenseKey: LICENSE_KEY });

const devices = await scanner.getScanners();      // ["Canon MF630", ...]
const pages = await scanner.scan({
  source:    devices[0],
  dpi:       300,
  color:     "color",       // "color" | "gray" | "bw"
  quality:   85,            // JPEG quality 1-100 for color/gray (b&w stays lossless)
  feeder:    false,         // true = use the document feeder (ADF)
  duplex:    false,         // two-sided (needs feeder)
  fastFeeder:false,         // ADF via TWAIN continuous feed — fast + reliable duplex on document scanners
  skipBlank: false,
  onPage:    blob => addThumbnail(URL.createObjectURL(blob))
});
console.log(`Scanned ${pages.length} page(s).`);   // pages: Blob[]

Scan options

FieldTypeNotes
sourcestringA name from getScanners().
dpinumbere.g. 100 / 150 / 200 / 300 / 600.
colorstring"color", "gray" or "bw".
qualitynumber1–100 (default 85). JPEG quality for color/gray; bw is always lossless PNG. Higher = larger file, better for OCR.
feederbooleanUse the automatic document feeder.
duplexbooleanTwo-sided; requires feeder:true.
fastFeederbooleanDrive the ADF over TWAIN's continuous feed instead of WIA — much faster and reliable duplex on dedicated document scanners (EPSON DS, Fujitsu fi). Leave off for multifunction printers; falls back to WIA automatically if TWAIN fails. Requires feeder:true.
skipBlankbooleanDiscard blank pages.
formatstring"images" (default, resolves to Blob[]) or "pdf" (a single PDF Blob).
onPagefunctionCalled with each page Blob as it arrives.

PDF output

Get a single PDF instead of images — either from scan() or from pages you already have.

// scan straight to a PDF Blob
const pdf = await scanner.scan({ source: devices[0], feeder: true, format: "pdf" });

// or build one from pages later
const pdf2 = await DQScanner.convertToPdf(pages, { dpi: 300, quality: 0.85 });

Manage pages (edit before upload)

Collect scanned and imported pages in a buffer, then rotate, replace, reorder or remove them before exporting.

const buffer = DQScanner.createBuffer();
buffer.on("change", b => renderThumbnails(b));

await scanner.scan({ source: devices[0], feeder: true, into: buffer });

// Import existing files (JPG / PNG / PDF) — PDF pages are rasterized for you
const added = await buffer.loadFromFile();          // opens a file picker

await buffer.rotate(0, 90);        // rotate the 1st page 90° (90 | 180 | 270)
buffer.replaceAt(1, someBlob);     // swap a page
buffer.insertAt(0, someBlob);      // insert at a position (default is append)
buffer.move(3, 0);                 // reorder: move page 4 to the front
buffer.removeAt(2);                // delete a page

const pdf = await buffer.toPdf();  // export the final document
buffer.clear();
MethodDescription
rotate(index, degrees)Rotate a page in place (90/180/270). Returns a Promise.
loadFromFile(opts?)File picker → load JPG/PNG/PDF (PDF pages rasterized). Resolves with the number of pages added. opts: { multiple, accept, scale, at }.
replaceAt(index, blob)Replace a page without removing/re-adding.
insertAt(index, blob)Insert at a position; returns the index used.
move(from, to)Reorder a page.
removeAt / clear / at / countRemove, clear, read a page, and the page count.

PDF import is powered by a bundled renderer served from your portal — your app doesn't need to add pdf.js.

TypeScript / Angular

Types are served next to the SDK: http://scanner.daleelteq.cloud/sdk/daleelteq-scanner.d.ts. Reference it in your project for full IntelliSense on the global DQScanner.

// angular.json -> architect.build.options.scripts
"scripts": [ "http://scanner.daleelteq.cloud/sdk/daleelteq-scanner.js" ]

// component.ts
const scanner = await DQScanner.create({ licenseKey: environment.scannerKey });
const pdf = await scanner.scan({ source: (await scanner.getScanners())[0], format: "pdf" });

If the service isn't installed

getScanners()/scan() wait for the service to appear. To detect whether it's installed and prompt a download, use ensureRunning():

if (!(await scanner.ensureRunning({ timeout: 12000 }))) {
  // Not detected on this machine — send the user to install it.
  showInstallDialog();
}

Handling errors

A rejected create() tells you exactly why the key was refused.

try {
  const scanner = await DQScanner.create({ licenseKey: LICENSE_KEY });
} catch (e) {
  if (e.name === "LicenseError") showBanner(e.message);  // expired / wrong domain / invalid
  else throw e;
}

Troubleshooting

SymptomFix
Never connectsMake sure the DQ Scanner service is installed and running (tray icon).
LicenseError: not valid for this domainUse a key issued for this host (or a wildcard).
No scanners listedConfirm the scanner's driver is installed and the device is on.
Feeder scan failsLoad paper before scanning.

Start free trial → Try the demo →