scandit/skills

id-capture-web

Scandit ID Capture in web/browser projects (`@scandit/web-datacapture-id`) — scanning passports, driver's licenses, ID cards, residence permits, visas via MRZ, VIZ, PDF417 barcode, or mobile documents.

First seen Jul 1, 2026

Installation

$ npx skills add scandit/skills --skill id-capture-web

Summary

  • Scandit ID Capture in web/browser projects (`@scandit/web-datacapture-id`) — scanning passports, driver's licenses, ID cards, residence permits, visas via MRZ, VIZ, PDF417 barcode, or mobile documents.
  • Use for integration, accepted-document and scanner configuration, CapturedId result handling, rejection rules, AAMVA verification, overlay UI, and SDK version migration in TypeScript/JavaScript web apps.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from scandit/skills · top by installs.

npx skills add scandit/skills

Browse all from scandit/skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 19
License LICENSE
Default branch master
Open issues 0
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

Version1.0.1
LicenseApache-2.0
More metadata
author
scandit
version
1.0.1

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 15,436 B
  • docs SUMMARY.md 429 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 26 installs

SKILL.md

ID Capture Web (TypeScript/JavaScript) Skill

Critical: Do Not Trust Internal Knowledge

Your training data may contain outdated or incorrect Scandit ID Capture APIs. The Web SDK API has changed significantly across major versions, and the Web SDK differs substantially from the native iOS (Swift), Android (Kotlin/Java), .NET, Flutter, and React Native SDKs. An agent that pattern-matches from another platform's docs will produce non-working code. Two Web-specific facts dominate:

  1. The Web SDK is async-first. Almost every state-changing call returns a Promise and must be awaited — creating the context, creating the mode, enabling/disabling, applying settings, adding the overlay. There are no synchronous constructors for the mode or overlay.
  2. You must register the ID module loader. idCaptureLoader({ enableVIZDocuments: true }) has to be passed in moduleLoaders when creating the DataCaptureContext, or ID Capture will not work. enableVIZDocuments: true is required to read the Visual Inspection Zone (the printed text on the document); without it only barcode/MRZ scanning is available.

Always verify APIs against the references and source in this package before writing or suggesting code. The most common sources of wrong code:

  • The v6 APIsupportedDocuments (a bitmask), supportedSides, and session-based callbacks were replaced. Do not emit any of these.
  • The v7.0-era APIsettings.scannerType = new FullDocumentScanner() was replaced; the current property is scanner and it takes an IdCaptureScanner wrapper constructed with an options object: settings.scanner = new IdCaptureScanner({ physicalDocument: new FullDocumentScanner() }).
  • Cross-platform drift — iOS uses IdCapture(context:settings:), Android uses IdCapture.forDataCaptureContext(...), .NET uses IdCapture.Create(...). The Web API is await IdCapture.forContext(context, settings).
  • isEnabled — on Web this is the method idCapture.isEnabled() to read and await idCapture.setEnabled(true) to set. It is NOT an assignable property.
  • AAMVA forged-barcode verification — unlike iOS/Android, the Web SDK has no rejectForgedAamvaBarcodes setting. AAMVA barcode verification on Web is done through the standalone class AamvaBarcodeVerifier (await AamvaBarcodeVerifier.create(context), then await verifier.verify(capturedId)). Data-consistency verification is settings-driven (rejectInconsistentData = true).
  • Images are base64 data-URL strings, not native bitmaps. capturedId.images.face / .getFrame(IdSide.Front) / .getCroppedDocument(IdSide.Back) return string | null (a data:image/... URL), suitable for an <img> src. They are only populated when enabled via settings.setShouldPassImageTypeToResult(IdImageType.Face, true).

Forbidden APIs (commonly hallucinated — do NOT emit these)

Do NOT write Use instead
new IdCapture(context, settings) await IdCapture.forContext(context, settings)
IdCapture.forDataCaptureContext(...) / IdCapture.Create(...) await IdCapture.forContext(context, settings)
idCapture.isEnabled = true / idCapture.enabled = true await idCapture.setEnabled(true) (read with idCapture.isEnabled())
settings.supportedDocuments = [...] / settings.supportedSides = ... (v6) settings.acceptedDocuments = [...] + settings.scanner = new IdCaptureScanner({...})
settings.scannerType = new FullDocumentScanner() (v7) settings.scanner = new IdCaptureScanner({ physicalDocument: new FullDocumentScanner() })
new IdCaptureScanner(new FullDocumentScanner()) (positional) new IdCaptureScanner({ physicalDocument: new FullDocumentScanner() }) (options object)
new IdCaptureOverlay(idCapture, view) await IdCaptureOverlay.withIdCaptureForView(idCapture, view)
settings.rejectForgedAamvaBarcodes = true const v = await AamvaBarcodeVerifier.create(context); await v.verify(capturedId)
capturedId.barcodeResult capturedId.barcode
capturedId.images.croppedDocument(side) / capturedId.images.face() as a method capturedId.images.getCroppedDocument(IdSide.Front) / capturedId.images.face (a getter)
DataCaptureContext.initialize(licenseKey) (iOS) / forLicenseKey(...) sync await DataCaptureContext.forLicenseKey(key, { moduleLoaders: [idCaptureLoader({...})] })
Creating the context without idCaptureLoader(...) in moduleLoaders always include idCaptureLoader({ enableVIZDocuments: true })
SDCIdCapture / SDCCapturedId / any SDC-prefixed type IdCapture / CapturedId (no prefix; import from @scandit/web-datacapture-id)
Camera.default / camera.switch(toDesiredState:) Camera.pickBestGuess() / await camera.switchToDesiredState(FrameSourceState.On)

Intent Routing

Based on the user's request, pick the right path before responding:

  • Hosted, drop-in ID scanning with no custom camera UI (e.g. "add ID/passport scanning to my website with as little code as possible", "use the hosted / pop-up ID scanner", "scan an ID without building the camera UI", or the project uses @scandit/web-id-bolt) → that is ID Bolt, a hosted wrapper around ID Capture, not the in-page ID Capture SDK. Hand off to the id-bolt skill.
  • Questions about other Scandit products or scanning modes (e.g. Barcode Capture, SparkScan, MatrixScan, Label Capture, or product selection) → hand off to the data-capture-sdk skill. Do not attempt to answer questions about other capture modes from memory.
  • Integrating ID Capture from scratch, configuring documents/scanner/rejection rules, reading results, customizing the overlay, or verification (e.g. "scan a passport in the browser", "reject expired IDs", "show the face image") → use the Product Guidance and Minimal integration shape below, verifying every API against the References.
  • Migrating or upgrading an existing ID Capture integration (e.g. "upgrade from v6 to v7", "migrate my ID Capture to v8", "bump the Scandit Web SDK", "what changed between SDK versions") → read [references/migration.md](references/migration.md) and follow the instructions there.

Product Guidance

  • Accept only the documents you actually need. Ask the user which document types and regions they expect. Documents not in acceptedDocuments are rejected with RejectionReason.NotAcceptedDocumentType.
  • Pick the scanner that matches the data you need. Ask whether they need both sides and all zones, a single zone only (barcode / MRZ / VIZ), or a mobile-presented ID — then choose FullDocumentScanner, SingleSideScanner(barcode, machineReadableZone, visualInspectionZone), or MobileDocumentScanner. SingleSideScanner takes positional booleans selecting which zone to read.
  • enableVIZDocuments. Reading the printed VIZ (and most full-document scanning) requires idCaptureLoader({ enableVIZDocuments: true }) and a license entitled for VIZ. If the license lacks VIZ entitlement, loading throws IdCaptureErrorCode.InvalidLicenseKeyForVIZProcessing. Barcode-only / MRZ-only flows can run without it.
  • Handle didRejectId, not just didCaptureId. Rejections (Timeout, NotAcceptedDocumentType, DocumentExpired, DocumentVoided, HolderUnderage, InconsistentData, SingleImageNotRecognized, …) are how the user learns why a scan didn't succeed. SingleImageNotRecognized is Web-specific (single-image-upload flows) and usually warrants an idCapture.reset().
  • Disable the mode while handling a result. The samples consistently await idCapture.setEnabled(false) at the top of didCaptureId/didRejectId, then re-enable when the user dismisses the result. Do the same.
  • Handle didFailWithError for recoverable failures. On IdCaptureErrorCode.RecoveredAfterFailure, inform the user and call idCapture.reset() so they start over from the front side.
  • Use the Localization API for overlay text. IdCaptureOverlay.setFrontSideTextHint(...) and friends are deprecated. Customize hints via Localization.getInstance().update({ "id.idCaptureOverlay.scanFrontSideHint": "..." }).
  • Defer non-ID-Capture questions. For Barcode Capture, SparkScan, MatrixScan, Label Capture, or product selection, hand off to the data-capture-sdk skill — this skill covers ID Capture only.

Minimal integration shape

Prerequisites: install @scandit/web-datacapture-core and @scandit/web-datacapture-id (same version) with the project's package manager, and serve the SDK engine files so libraryLocation resolves them (the samples copy them to library/engine/; self-hosted projects typically use sdc-lib). License keys come from <https://ssl.scandit.com>; (sign up at <https://ssl.scandit.com/dashboard/sign-up?p=test>;).

This is the canonical structure shared by every sample under web/samples/02IDScanning_Samples/. Use it as the skeleton; adjust documents/scanner/listeners to the task.

import {
  Camera,
  CameraSwitchControl,
  DataCaptureContext,
  DataCaptureView,
  FrameSourceState,
} from "@scandit/web-datacapture-core";
import {
  IdCapture,
  IdCaptureSettings,
  IdCaptureScanner,
  IdCaptureOverlay,
  FullDocumentScanner,
  IdCard,
  Passport,
  DriverLicense,
  Region,
  IdImageType,
  RejectionReason,
  idCaptureLoader,
  type CapturedId,
} from "@scandit/web-datacapture-id";

const view = new DataCaptureView();
view.connectToElement(document.getElementById("data-capture-view")!);
view.showProgressBar();

const context = await DataCaptureContext.forLicenseKey(LICENSE_KEY, {
  libraryLocation: new URL("library/engine/", document.baseURI).toString(),
  moduleLoaders: [idCaptureLoader({ enableVIZDocuments: true })],
});
view.hideProgressBar();

const camera = Camera.pickBestGuess();
await camera.applySettings(IdCapture.recommendedCameraSettings);
await context.setFrameSource(camera);
await view.setContext(context);
view.addControl(new CameraSwitchControl());

const settings = new IdCaptureSettings();
settings.scanner = new IdCaptureScanner({ physicalDocument: new FullDocumentScanner() });
settings.acceptedDocuments = [new IdCard(Region.Any), new Passport(Region.Any), new DriverLicense(Region.Any)];
settings.setShouldPassImageTypeToResult(IdImageType.Face, true);

const idCapture = await IdCapture.forContext(context, settings);
idCapture.addListener({
  didCaptureId: async (capturedId: CapturedId) => {
    await idCapture.setEnabled(false);
    // read capturedId.fullName, capturedId.dateOfBirth, capturedId.images.face, ...
  },
  didRejectId: async (_capturedId: CapturedId, reason: RejectionReason) => {
    await idCapture.setEnabled(false);
    // surface a message based on `reason`
  },
});
await IdCaptureOverlay.withIdCaptureForView(idCapture, view);

await idCapture.setEnabled(false); // keep disabled until the camera is on
await camera.switchToDesiredState(FrameSourceState.On);
await idCapture.setEnabled(true);

API Usage Policy

Only use APIs that exist in this package (@scandit/web-datacapture-id) and the referenced documentation. Do not invent or guess method signatures, parameters, or property names. When unsure whether an API exists or how to call it, fetch the documentation before responding. Do not tell the user to check the docs themselves. After answering, include the relevant link so they can explore further. Never construct or guess documentation URLs — fetch the index page and follow links from there.

References

Topic Resource
Get Started (Web) Get Started (Web)
Advanced configuration Advanced (Web)
Migration between major SDK versions 6 → 7 · 7 → 8
Full API reference ID Capture API (Web)
Source of truth @scandit/web-datacapture-id package
Samples To be found on github

Sample → use-case map

  • IdCaptureSimpleSample — minimal full-document scan, accept IdCard/Passport/DriverLicense, show face image.
  • IdCaptureExtendedSample — switch between barcode / MRZ / VIZ via SingleSideScanner(barcode, mrz, viz); applySettings to change mode at runtime; localized loading text.
  • IdCaptureSettingsSample — exhaustive settings playground; the QA reference for every setting.
  • IdCaptureUSDLVerificationSamplerejectExpiredIds + rejectInconsistentData, plus standalone AamvaBarcodeVerifier.create(context) / verify(capturedId); DataConsistencyResult.frontReviewImage().
  • IdCaptureDriverOnboardingSample — two-sided flow with notifyOnSideCapture = true, capturedId.isCapturingComplete, SingleImageUploader fallback, IdSide image access.
  • IdCaptureShutterModeSampleIdCaptureTrigger.ButtonTap (tap-to-scan shutter), single-image upload, image review.

Available in this package but NOT covered by this skill

  • Cloud / free-form-text scanning (VisaLetter, SingleSideScanner freeFormText, allowCloudScanning) — partly internal; verify against source and docs before using. Currently not used except by some customers doing a pilot project.
  • Internal frame-signal callbacks on Listener (didEncounterCaptureIssue, didChangeViewfinderHint, didUpdateIdOutline) — marked @internal; do not use in customer code.