This project contains Datachecker's AutoCapture tool, that captures images of identity documents (ID/Passport/Driver license). The tool only takes a capture once a document is detected and it passes the quality control.
npm install @datachecker/autocaptureThis project contains Datachecker's AutoCapture tool, that captures images of paper documents + identity documents (ID/Passport/Driver license). The tool only takes a capture once a document is detected and it passes the quality control.
The tool will be run in the browser and is therefore written in JavaScript.
The tool performs the following checks:
- Is the environment not too dark (under exposure)?
- Is there a document?
- Is the detected document not too far?
- Is the detected document not too close?
- Is the image sharp?
Please visit Datachecker API documentation.
- Datachecker OAuth Token
- Datachecker SDK Token
The SDK requires a browser that supports at least ECMAScript 12 (ES12). It is highly recommended to use the latest version of your preferred browser to ensure compatibility and access to the latest features and security updates.
Using the latest browser versions will ensure that all modern JavaScript features required by the SDK are supported.
1. Request OAUTH Token
2. Put OAuth in header
3. SDK configuration (add SDK token)
4. Run SDK
Datachecker uses OAuth authorization. In order to request the SDK token you will need to provide a valid OAuth token in the header.
Example header:
``javascriptBearer ${response.accessToken}
header = {'Authorization': }`
This OAuth token can be retrieved with the Datachecker OAuth Token API. The scope "productapi.sdk.read" needs to be present to make use of the SDK token. If this scope is missing you will not be able to retrieve an SDK token.
Example OAuth:
`javascript`
fetch(
method: 'POST',
body: JSON.stringify({
"clientId":
"clientSecret":
"scopes": [
"productapi.sdk.read",
]
})
})
.then(response => response.json())
Note: Contact Datachecker for client_id and client_secret.
The SDK is locked. In order to use the SDK in production a token is required. The application can only be started with a valid token. This token is a base64 string. The token can be generated by calling the Datachecker SDK Token API.
Example:
`javascriptBearer
fetch(
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': `
}
})
.then(response => response.json())
To run this tool, you will need initialise with the following variables.
| ATTRIBUTE | FORMAT | DEFAULT VALUE | EXAMPLE | NOTES |
| ------------------- | ----------------------- | ------------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| ALLOWED_DOCUMENTS | object | see ALLOWED DOCUMENTS | see ALLOWED DOCUMENTS | optionalAPPROVAL
Enable or disable flipping of certain documents. |
| | bool | false | false | optionalASSETS_FOLDER
Approval screen after capture as an extra quality check. |
| | string | "" | "../" | optionalASSETS_MODE
Specifies location of locally hosted assets folder. (see Asset Fetching Configuration) |
| | string | "CDN" | "LOCAL" | optionalBACKGROUND_COLOR
Specifies mode of asset fetching, either through CDN or locally hosted assets. (see Asset Fetching Configuration) |
| | string (Hex color code) | "#1d3461" | "#1d3461" | optionalCAPTURE_BTN_AFTER
Specifies the background color using a hex color code. |
| | int | 0 (AutoCapture) / 5000 (PaperCapture) | 0 | optional0
Configures a delay for the capture button's appearance in milliseconds. Setting this parameter to disables the button. Use of the capture button is discouraged, as it bypasses the automatic quality control checks. It is included only as a fallback mechanism. If you choose to enable it, it is recommended to show the button only after a delay, not immediately at the start. |CONTAINER_ID
| | string | | "AC_mount" | requireddiv
_div id_ to mount tool on. If the does not exist it will be created and placed in
. |
| DEBUG | bool | false | false | optional
When debug is true more detailed logs will be visible. |
| DESKTOP_MODE | bool | false | false | optional
Enables all cameras for testing/development purposes. FOR TESTING ONLY - DO NOT USE IN PRODUCTION. Desktop cameras are often labeled with facingMode: 'user' instead of 'environment', which would normally be filtered out. This mode bypasses camera filtering to allow testing on desktop devices, including virtual cameras. Production environments should always use false to ensure only back-facing cameras (environment) are available, preventing accidental use of front-facing cameras on mobile devices. |
| LANGUAGE | string | "nl" | "nl" | required
Notifications in specific language. |
| onComplete | javascript function | | function(data) {console.log(data)} | required
Callback function on _complete_. |
| onError | javascript function | function(error) {console.log(error)} | function(error) {console.log(error)} | required
Callback function on _error_. |
| onUserExit | javascript function | function(error) {console.log(error)} | function(error) {window.history.back()} | required
Callback function on _user exit_. |
| ROI_MODE | string | "landscape-landscape" | portrait-landscape | optional
Frame orientation options: "portrait-landscape", "landscape-landscape" |
| SDK_MODE | string | "autocapture" | "papercapture" | optional
Specifies mode of the SDK, supported modes are: "autocapture", "papercapture" (see SDK Modes) |
| TOKEN | string | | see SDK Token | required
Datachecker SDK token. |SDK Modes
The SDK offers two operational modes:
- AutoCapture: Optimized for real-time capture of identity documents such as IDs, passports, and driver licenses. A capture is triggered only when a document is detected and passes all quality checks.
- PaperCapture: Tailored for capturing paper documents (e.g., work permits). Like AutoCapture, it ensures a capture occurs only after document detection and successful quality validation.
Refer to Configuration for details on how to set the desired mode.
$3
`javascript
let AC = new AutoCapture();
AC.init({
CONTAINER_ID: ...,
LANGUAGE: ...,
TOKEN: ...,
SDK_MODE: "papercapture",
onComplete: ...,
onError: ...,
onUserExit: ...
});
`Asset fetching Configuration
AutoCapture requires fetching assets, which can be done either through a CDN or by hosting them locally. Configure this in the tool settings as follows:
$3
`javascript
// configuration
{
ASSETS_MODE: "CDN",
// other configurations
}
`$3
To host assets locally, first copy them to your desired location:
`bash
cp -r dist/assets/ path/to/hosted/assets/
`Then, configure the tool to use these local assets:
`javascript
// configuration
{
ASSETS_MODE: "LOCAL",
ASSETS_FOLDER: "path/to/hosted/assets/",
// other configurations
}
`For comphrehensive integration examples, please refer to our Integration Examples.
$3
To ensure compatibility:
- Separate Asset Versioning: The assets directory contains a version file, separate from the main file's version.
- Compatibility Check: The main file will perform a version check and throw an error if the versions are incompatible.
Content Security Policy (CSP)
AutoCapture is designed to work with Content Security Policy (CSP) enabled. The SDK requires specific CSP directives to load assets (e.g., scripts, models, images) and execute WebAssembly for document detection.
$3
Ensure your CSP policy includes the following directives. Adjust domains based on your environment (e.g., use
https://developer.datachecker.nl for Datachecker production api).-
default-src 'self';
- script-src 'self' https://cdn.jsdelivr.net 'wasm-unsafe-eval' 'unsafe-inline' blob:;
- style-src 'self' 'unsafe-inline';
- connect-src 'self' https://developer.datachecker.nl https://cdn.jsdelivr.net data:;
- img-src 'self' data: blob: https://cdn.jsdelivr.net;
- worker-src 'self' blob:;
- object-src 'self' blob:;
- frame-src 'self' blob:;
- base-uri 'none';Handling callbacks
Within the application, you can take advantage of four callback functions to enhance the user experience and manage the flow of your process.
Note: When integrating the application into Native Apps using web views, it's essential to adapt and utilize these callback functions according to the conventions and requirements of the native platforms (e.g., iOS, Android). Native app development environments may have specific ways of handling JavaScript callbacks, and you should ensure seamless communication between the web view and the native code.
Example Web (JS):
`javascript
let AC = new AutoCapture();
AC.init({
CONTAINER_ID: 'AC_mount',
LANGUAGE: 'en',
TOKEN: "",
onComplete: function(data) {
console.log(data);
},
onError: function(error) {
console.log(error)
},
onUserExit: function(error) {
console.log(error);
window.history.back();
}
});
`| ATTRIBUTE | FORMAT | DEFAULT VALUE | EXAMPLE | NOTES |
| ------------- | ------------------- | -------------------------------------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------- |
|
onComplete | javascript function | | function(data) {console.log(data)} | required
Callback that fires when all interactive tasks in the workflow have been completed. |
| onError | javascript function | function(error) {console.log(error)} | function(error) {console.log(error)} | required
Callback that fires when an _error_ occurs. |
| onUserExit | javascript function | function(error) {console.log(error)} | function(error) {window.history.back()} | required
Callback that fires when the user exits the flow without completing it. |$3
This callback function will be called once all the tasks within the workflow succesfully have been completed. This callback function is required. The
data parameter within the function represents the output of the completed process. You can customize this function to handle and display the data as needed.Example Web (JS):
Within the example below we are logging the output (
data) to console.`javascript
let AC = new AutoCapture();
AC.init({
...,
onComplete: function(data) {
console.log(data);
}
});
`$3
This callback can be used to alert users when something goes wrong during the process. This callback function is required. The
error parameter within the function contains information about the specific error encountered, allowing you to log or display error messages for debugging or user guidance. The errors that are thrown are either known or unknown. The known errors can be found within the Languages dictionary. On the other hand, the unknown errors will be thrown as is. Example Web (JS):
Within the example below we are logging the output (
error) to console.`javascript
let AC = new AutoCapture();
AC.init({
...,
onError: function(error) {
console.log(error)
}
});
`$3
This callback can be used to implement actions like returning users to the previous page or prompting them for confirmation before exiting to ensure they don't lose any unsaved data or work. This callback function is required. The
error parameter within the function contains information about the specific error encountered, allowing you to log or display error messages for debugging or user guidance. The error that is thrown is "exit".Example Web (JS):
Within the example below we are logging the output (
error) to console. Finally, we move back one page in the session history with window.history.back().`javascript
let AC = new AutoCapture();
AC.init({
...,
onUserExit: function(error) {
console.log(error);
window.history.back()
}
});
`Usage/Examples
The tool first needs to be initialised to load all the models.
Once its initialised, it will be started.
`javascript
let AC = new AutoCapture();
AC.init({
CONTAINER_ID: ...,
LANGUAGE: ...,
TOKEN: ...,
onComplete: ...,
onError: ...,
onUserExit: ...
});
`To stop the camera and empty the container with its contents the
stop function can be called. This function will automatically be called within onComplete, onError and onUserExit thus do not have to be called within your own custom versions of these functions.`javascript
AC.stop();
`If you wish to completely remove the container (identified by
CONTAINER_ID), use the remove command:`javascript
AC.remove();
`Example below:
`javascript
let AC = new AutoCapture();
AC.init({
CONTAINER_ID: 'AC_mount',
LANGUAGE: 'nl',
TOKEN: "",
onComplete: function(data) {
console.log(data);
},
onError: function(error) {
console.log(error)
},
onUserExit: function(error) {
console.log(error);
window.history.back()
}
});
`Importing SDK
Import the SDK with one of the three methods: Script tag, ES6 or CommonJS.
$3
Easily add AutoCapture to your HTML files using the Script Tag method.
`html
`$3
For projects using NPM and a module bundler like Webpack or Rollup, you can import AutoCapture as an ES6 module or with CommonJS require syntax.
`js
// Import AutoCapture in your JavaScript file// ES6 style import
import AutoCapture from '@datachecker/autocapture';
// CommonJS style require
let AutoCapture = require('@datachecker/autocapture')
`Demo
`html
AutoCapture
`For comphrehensive integration examples, please refer to our Integration Examples.
Languages
There are two ways in which notifications can be loaded: from file, from object (json).
$3
The languages can be found in
assets/language/. The current support languages are en and nl. More languages could be created.The notifications can be loaded in
configuration like the following:`javascript
let AC = new AutoCapture();
AC.init({
LANGUAGE: 'en',
...
`To create support for a new language, a js file needs to be created with specific keys.
The keys can be derived from the current language js files (
assets/language/en.js).Example:
`javascript
var LANGUAGE = {
approval_prompt: "Is the image right?",
capture_error: "We were unable to capture an image. Camera access is required.",
camera_selection: "Please select the back camera",
confirm: "Accept",
continue: "Continue",
corners: "Not all corners detected",
exp_bright: "Environment is too bright",
exp_dark: "Environment is too dark",
flip: "Flip the document",
flip_backside: "Flip the document to the backside",
flip_frontside: "Flip the document to the frontside",
focus: "Hold still...",
glare: "Glare detected",
occlusion: "Document is occluded",
size: "Move closer",
start_prompt: "Tap to start",
std_msg_0: "Place your document",
retry: "Try again",
rotate_phone: "Please rotate your phone upright",
tutorial: "Follow the instructions"
}
`$3
Notifications can also be loaded as a json object like the following:
`javascript
let AC = new AutoCapture();
AC.init({
LANGUAGE: JSON.stringify(
{
approval_prompt: "Is the image right?",
capture_error: "We were unable to capture an image. Camera access is required.",
camera_selection: "Please select the back camera",
confirm: "Accept",
continue: "Continue",
corners: "Not all corners detected",
exp_bright: "Environment is too bright",
exp_dark: "Environment is too dark",
flip: "Flip the document",
flip_backside: "Flip the document to the backside",
flip_frontside: "Flip the document to the frontside",
focus: "Hold still...",
glare: "Glare detected",
occlusion: "Document is occluded",
size: "Move closer",
start_prompt: "Tap to start",
std_msg_0: "Place your document",
retry: "Try again",
rotate_phone: "Please rotate your phone upright",
tutorial: "Follow the instructions"
}
),
...
`Models
The tool uses a collection of neural networks. Make sure that you host the full directory so the models can be accessed. The models path can be configured. (see Configuration)
The models are located under
models/.Allowed documents
The
ALLOWED_DOCUMENTS setting lets you specify which documents should permit flipping and which should not. This allows you to control how the application handles different types of documents, ensuring that the capture process meets your requirements.Example:
`javascript
let AC = new AutoCapture();
AC.init({
CONTAINER_ID: 'AC_mount',
ALLOWED_DOCUMENTS: {
IDENTITY_CARD: ['FRONT', 'BACK'], // Two entries, so flipping is needed
PASSPORT: ['FRONT', 'BACK'], // Two entries, so flipping is needed
DUTCH_PASSPORT: undefined, // Dutch passport will be copied from PASSPORT settings if undefined
RESIDENCE_PERMIT: ['FRONT', 'BACK'], // Two entries, so flipping is needed
DRIVING_LICENSE: ['FRONT', 'BACK'], // Two entries, so flipping is needed
},
TOKEN: "",
onComplete: function (data) {
console.log(data)
},
onError: function(error) {
console.log(error)
},
onUserExit: function (error) {
console.log(error)
window.history.back()
}
})
`Output
The SDK will output in the following structure:
`json
{
"image": ["...base64_img"],
"meta": [
{
"angle": "...",
"coordinates": [
["...", "..."],
["...", "..."],
["...", "..."],
["...", "..."]
],
"force_capture": "...",
"device": "..."
}
],
"token": "sdk_token"
}
`Example:
`json
{
"image": ["iVBORw0KGgoAAAANSUhEUgAAAysAAAS..."],
"meta": [
{
"angle": 0,
"coordinates": [
[0, 0],
[0, 100],
[150, 100],
[150, 0]
],
"force_capture": false,
"device": "Back Camera"
}
],
"token": "sdk_token"
}
``