Document bundle
Processing of multiple different documents.
Verification of a bundle of documents is one of the most common use cases in document processing. Companies receive large amounts of documents every day. These documents require not only to be verified, but also to be identified before undergoing a precise processing workflow.
Introduction
Datakeen's OCR service automatically recognizes the document type to select the correct endpoint. It is then able to authenticate the document and extract information from each page. The platform handles images (JPG, PNG) and PDFs of these document types:
- ID card
- Passport
- Residence permit
- Tax statement
- Proof of address
- Payslip
- Driver's licence
- Bank account details.
Setting up the API
The synchronous API model can be used to operate on multiple documents at the same time.
API token is required
In order to perform any call, you will need an API token that can be retrieved thanks your API credentials. To learn about authentification, please refer to this page
curl --request POST \
--url https://api.datakeen.co/api/v1/reco/multi-doc \
--header 'accept: application/json' \
--header 'content-type: application/json'
npm install api --save
const sdk = require('api')('@datakeen/v1.4.0#ax268r1ilnd0liqe');
sdk.postRecoId()
.then(({ data }) => console.log(data))
.catch(err => console.error(err));
require 'uri'
require 'net/http'
url = URI("https://api.datakeen.co/api/v1/reco/multi-doc")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["accept"] = 'application/json'
request["content-type"] = 'application/json'
response = http.request(request)
puts response.read_body
composer require guzzlehttp/guzzle
<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.datakeen.co/api/v1/reco/multi-doc', [
'headers' => [
'accept' => 'application/json',
'content-type' => 'application/json',
],
]);
echo $response->getBody();
python -m pip install requests
import requests
url = "https://api.datakeen.co/api/v1/reco/multi-doc"
headers = {
"accept": "application/json",
"content-type": "application/json"
}
response = requests.post(url, headers=headers)
print(response.text)
CURL *hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, stdout);
curl_easy_setopt(hnd, CURLOPT_URL, "https://api.datakeen.co/api/v1/reco/multi-doc");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "accept: application/json");
headers = curl_slist_append(headers, "content-type: application/json");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);
CURLcode ret = curl_easy_perform(hnd);
dotnet add package RestSharp
using RestSharp;
var options = new RestClientOptions("https://api.datakeen.co/api/v1/reco/multi-doc");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
var response = await client.PostAsync(request);
Console.WriteLine("{0}", response.Content);
CURL *hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, stdout);
curl_easy_setopt(hnd, CURLOPT_URL, "https://api.datakeen.co/api/v1/reco/multi-doc");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "accept: application/json");
headers = curl_slist_append(headers, "content-type: application/json");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);
CURLcode ret = curl_easy_perform(hnd);
(require '[clj-http.client :as client])
(client/post "https://api.datakeen.co/api/v1/reco/multi-doc" {:content-type :json
:accept :json})
package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.datakeen.co/api/v1/reco/multi-doc"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("accept", "application/json")
req.Header.Add("content-type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}
POST /api/v1/reco/multi-doc HTTP/1.1
Accept: application/json
Content-Type: application/json
Host: api.datakeen.co
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.datakeen.co/api/v1/reco/multi-doc")
.post(null)
.addHeader("accept", "application/json")
.addHeader("content-type", "application/json")
.build();
Response response = client.newCall(request).execute();
const options = {
method: 'POST',
headers: {accept: 'application/json', 'content-type': 'application/json'}
};
fetch('https://api.datakeen.co/api/v1/reco/multi-doc', options)
.then(response => response.json())
.then(response => console.log(response))
.catch(err => console.error(err));
val client = OkHttpClient()
val request = Request.Builder()
.url("https://api.datakeen.co/api/v1/reco/multi-doc")
.post(null)
.addHeader("accept", "application/json")
.addHeader("content-type", "application/json")
.build()
val response = client.newCall(request).execute()
#import <Foundation/Foundation.h>
NSDictionary *headers = @{ @"accept": @"application/json",
@"content-type": @"application/json" };
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://api.datakeen.co/api/v1/reco/multi-doc"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:@"POST"];
[request setAllHTTPHeaderFields:headers];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(@"%@", httpResponse);
}
}];
[dataTask resume];
open Cohttp_lwt_unix
open Cohttp
open Lwt
let uri = Uri.of_string "https://api.datakeen.co/api/v1/reco/multi-doc" in
let headers = Header.add_list (Header.init ()) [
("accept", "application/json");
("content-type", "application/json");
] in
Client.call ~headers `POST uri
>>= fun (res, body_stream) ->
(* Do stuff with the result *)
$headers=@{}
$headers.Add("accept", "application/json")
$headers.Add("content-type", "application/json")
$response = Invoke-WebRequest -Uri 'https://api.datakeen.co/api/v1/reco/multi-doc' -Method POST -Headers $headers
library(httr)
url <- "https://api.datakeen.co/api/v1/reco/multi-doc"
response <- VERB("POST", url, content_type("application/json"), accept("application/json"))
content(response, "text")
import Foundation
let headers = [
"accept": "application/json",
"content-type": "application/json"
]
let request = NSMutableURLRequest(url: NSURL(string: "https://api.datakeen.co/api/v1/reco/multi-doc")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error as Any)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse)
}
})
dataTask.resume()
API Response
An instance of the usual response is displayed in the following JSON. You will find the complete information, including extraction and checks. More detailed examples of each extracted field are given below.
{
"status": 200,
"message": "Success",
"results": {
"entities": [
{
"lastName": "PERRET",
"firstName": "Adrien alex tom",
"id": "a08f57a4-c493-4661-85f5-3b7a219452ce"
}
],
"documents": [
{
"origin": "",
"type": "id-card",
"path": "",
"pages": [
{
"path": "CNI_2_recto.jpg",
"type": "",
"num": 0
},
{
"path": "CNI_2_verso.jpg",
"type": "",
"num": 0
}
],
"entities": [
"a08f57a4-c493-4661-85f5-3b7a219452ce"
],
"cardType": "national_id_card_fr_2003",
"cardSide": "front",
"status": 200,
"message": "",
"extractedInformation": {
"firstName": {
"value": "ADRIEN ALEX TOM",
"confidence": 0.7297601884925768,
"bbox": {
"topleft": [
0.4517351046735753,
0.31005804443359375
],
"width": 0.26760904337183394,
"height": 0.0521786092122396,
"text": "",
"page": {
"num": 0,
"width": null,
"height": null
},
"confidence": null
}
},
"lastName": {
"value": "PERRET",
"confidence": 0.7673592247462153,
"bbox": {
"topleft": [
0.40635323300817894,
0.22442659505208334
],
"width": 0.10140292684759034,
"height": 0.04229313151041664,
"text": "",
"page": {
"num": 0,
"width": null,
"height": null
},
"confidence": null
}
},
"birthDate": {
"value": "12.06.1986",
"confidence": 0.7499997241493617,
"bbox": {
"topleft": [
0.6803472637011903,
0.3985098063151042
],
"width": 0.15491936488625702,
"height": 0.061960896809895805,
"text": "",
"page": {
"num": 0,
"width": null,
"height": null
},
"confidence": null
}
},
"birthPlace": {
"value": "TOULOUSE",
"confidence": 0.7788274649851097,
"bbox": {
"topleft": [
0.37684207651449636,
0.4592803955078125
],
"width": 0.13239163797747128,
"height": 0.039837402343749995,
"text": "",
"page": {
"num": 0,
"width": null,
"height": null
},
"confidence": null
}
},
"idNumber": {
"value": "131131207922",
"confidence": 0.7998268103096038,
"bbox": {
"topleft": [
0.45706150992502637,
0.15746223958333333
],
"width": 0.19060887091602663,
"height": 0.04784318033854168,
"text": "",
"page": {
"num": 0,
"width": null,
"height": null
},
"confidence": null
}
},
"address": {
"value": "7 RUE ROBERT MESURET TOULOUSE [ 31 ]",
"confidence": 0.7911399390273814,
"bbox": {
"topleft": [
0.16025752827152953,
0.3178355722774861
],
"width": 0.23427801282178687,
"height": 0.08097789934289601,
"text": "",
"page": {
"num": 1,
"width": null,
"height": null
},
"confidence": null
}
},
"deliveryDate": {
"value": "15.12.2013",
"confidence": 0.8432930034987791,
"bbox": {
"topleft": [
0.2004041504132097,
0.47214519382327513
],
"width": 0.13982599560140352,
"height": 0.03644494843064694,
"text": "",
"page": {
"num": 1,
"width": null,
"height": null
},
"confidence": null
}
},
"expiryDate": {
"value": "14.12.2023",
"confidence": 0.8250615282513749,
"bbox": {
"topleft": [
0.3052476006012951,
0.41769256797718457
],
"width": 0.15001202070746128,
"height": 0.04155225663693485,
"text": "",
"page": {
"num": 1,
"width": null,
"height": null
},
"confidence": null
}
},
"mrz": {
"value": "IDFRAPERRET<<<<<<<<<<<<<<<<<<<312009\n1311312079226ADRIEN<<<<<<<<<86061215",
"confidence": 0.8434976453842609,
"bbox": {
"topleft": [
0.0746036050019971,
0.7393212076822917
],
"width": 0.8592058865259109,
"height": 0.1524629720052083,
"text": "",
"page": {
"num": 0,
"width": null,
"height": null
},
"confidence": null
}
},
"spouseName": {
"value": "",
"confidence": null,
"bbox": {}
},
"gender": {
"value": "M",
"confidence": 0.9840775728225708,
"bbox": {
"topleft": [
0.4119699846736486,
0.41950309244791667
],
"width": 0.017829537168005394,
"height": 0.024433797200520857,
"text": "M",
"page": {
"num": 0,
"width": null,
"height": null
},
"confidence": 0.9840775728225708
}
},
"firstNameMRZ": {
"value": "ADRIEN",
"confidence": 0,
"bbox": {}
},
"lastNameMRZ": {
"value": "PERRET",
"confidence": 0,
"bbox": {}
},
"idNumberMRZ": {
"value": "131131207922",
"confidence": 0,
"bbox": {}
},
"birthDateMRZ": {
"value": "",
"confidence": 0,
"bbox": {}
},
"countryCode": {
"value": "FR",
"confidence": 0.9,
"bbox": {}
}
},
"controls": {
"mrzValidity": {
"confidence": 0.5,
"value": false
},
"mrzConformity": {
"confidence": 0.5,
"value": false
},
"dateValidity": {
"confidence": 0.8250615282513749,
"value": true
},
"dateValidityDelivery": {
"confidence": 0.8432930034987791,
"value": false
},
"photoIsPresent": {
"value": true,
"confidence": 0.978230893611908,
"bbox": {
"topleft": [
0.013986006379127502,
0.17877906560897827
],
"width": 0.3046953082084656,
"height": 0.5566860437393188
}
},
"rfSymbolIsPresent": {
"value": false,
"confidence": 0.8,
"bbox": {}
},
"waveIsPresent": {
"value": true,
"confidence": 0.8196049928665161,
"bbox": {
"topleft": [
0.8461538758128881,
0.20348837971687317
],
"width": 0.05994005873799324,
"height": 0.19622093439102173
}
},
"initialsIsPresent": {
"value": true,
"confidence": 0.8698996305465698,
"bbox": {
"topleft": [
0.2627372667193413,
0.19040697440505028
],
"width": 0.039960041642189026,
"height": 0.04505813866853714
}
},
"globalStatus": {
"value": false,
"confidence": 0.30000000000000004
}
}
}
]
},
"webhook": null
}
Entities
For each person found in the documents, the first and last names are returns in entities list.
entities | value |
---|---|
firstName | string |
lastName | string |
id | string |
"entities": [
{
"lastName": "PERRET",
"firstName": "Adrien alex tom",
"id": "a08f57a4-c493-4661-85f5-3b7a219452ce"
}
]
Documents format
For each document in the bundle, the type, the extracted information, the controls and the entity's id are returned.
For further documentation on the extracted information and on the processed controls, please refer to the type's specific documentation page.
documents | Value |
---|---|
type | string |
origin | string |
path | string |
pages | list |
entities | list |
extractedInformation | dict |
controls | dict |
"documents": [
{
"origin": "",
"type": "id-card",
"path": "",
"pages": [
{
"path": "CNI_2_recto.jpg",
"type": "",
"num": 0
},
{
"path": "CNI_2_verso.jpg",
"type": "",
"num": 0
}
],
"entities": [
"a08f57a4-c493-4661-85f5-3b7a219452ce"
],
"cardType": "national_id_card_fr_2003",
"cardSide": "front",
"status": 200,
"message": "",
"extractedInformation": {
"firstName": {
"value": "ADRIEN ALEX TOM",
"confidence": 0.7297601884925768,
"bbox": {
"topleft": [
0.4517351046735753,
0.31005804443359375
],
"width": 0.26760904337183394,
"height": 0.0521786092122396,
"text": "",
"page": {
"num": 0,
"width": null,
"height": null
},
"confidence": null
}
},
"lastName": {
"value": "PERRET",
"confidence": 0.7673592247462153,
"bbox": {
"topleft": [
0.40635323300817894,
0.22442659505208334
],
"width": 0.10140292684759034,
"height": 0.04229313151041664,
"text": "",
"page": {
"num": 0,
"width": null,
"height": null
},
"confidence": null
}
},
"birthDate": {
"value": "12.06.1986",
"confidence": 0.7499997241493617,
"bbox": {
"topleft": [
0.6803472637011903,
0.3985098063151042
],
"width": 0.15491936488625702,
"height": 0.061960896809895805,
"text": "",
"page": {
"num": 0,
"width": null,
"height": null
},
"confidence": null
}
},
"birthPlace": {
"value": "TOULOUSE",
"confidence": 0.7788274649851097,
"bbox": {
"topleft": [
0.37684207651449636,
0.4592803955078125
],
"width": 0.13239163797747128,
"height": 0.039837402343749995,
"text": "",
"page": {
"num": 0,
"width": null,
"height": null
},
"confidence": null
}
},
"idNumber": {
"value": "131131207922",
"confidence": 0.7998268103096038,
"bbox": {
"topleft": [
0.45706150992502637,
0.15746223958333333
],
"width": 0.19060887091602663,
"height": 0.04784318033854168,
"text": "",
"page": {
"num": 0,
"width": null,
"height": null
},
"confidence": null
}
},
"address": {
"value": "7 RUE ROBERT MESURET TOULOUSE [ 31 ]",
"confidence": 0.7911399390273814,
"bbox": {
"topleft": [
0.16025752827152953,
0.3178355722774861
],
"width": 0.23427801282178687,
"height": 0.08097789934289601,
"text": "",
"page": {
"num": 1,
"width": null,
"height": null
},
"confidence": null
}
},
"deliveryDate": {
"value": "15.12.2013",
"confidence": 0.8432930034987791,
"bbox": {
"topleft": [
0.2004041504132097,
0.47214519382327513
],
"width": 0.13982599560140352,
"height": 0.03644494843064694,
"text": "",
"page": {
"num": 1,
"width": null,
"height": null
},
"confidence": null
}
},
"expiryDate": {
"value": "14.12.2023",
"confidence": 0.8250615282513749,
"bbox": {
"topleft": [
0.3052476006012951,
0.41769256797718457
],
"width": 0.15001202070746128,
"height": 0.04155225663693485,
"text": "",
"page": {
"num": 1,
"width": null,
"height": null
},
"confidence": null
}
},
"mrz": {
"value": "IDFRAPERRET<<<<<<<<<<<<<<<<<<<312009\n1311312079226ADRIEN<<<<<<<<<86061215",
"confidence": 0.8434976453842609,
"bbox": {
"topleft": [
0.0746036050019971,
0.7393212076822917
],
"width": 0.8592058865259109,
"height": 0.1524629720052083,
"text": "",
"page": {
"num": 0,
"width": null,
"height": null
},
"confidence": null
}
},
"spouseName": {
"value": "",
"confidence": null,
"bbox": {}
},
"gender": {
"value": "M",
"confidence": 0.9840775728225708,
"bbox": {
"topleft": [
0.4119699846736486,
0.41950309244791667
],
"width": 0.017829537168005394,
"height": 0.024433797200520857,
"text": "M",
"page": {
"num": 0,
"width": null,
"height": null
},
"confidence": 0.9840775728225708
}
},
"firstNameMRZ": {
"value": "ADRIEN",
"confidence": 0,
"bbox": {}
},
"lastNameMRZ": {
"value": "PERRET",
"confidence": 0,
"bbox": {}
},
"idNumberMRZ": {
"value": "131131207922",
"confidence": 0,
"bbox": {}
},
"birthDateMRZ": {
"value": "",
"confidence": 0,
"bbox": {}
},
"countryCode": {
"value": "FR",
"confidence": 0.9,
"bbox": {}
}
},
"controls": {
"mrzValidity": {
"confidence": 0.5,
"value": false
},
"mrzConformity": {
"confidence": 0.5,
"value": false
},
"dateValidity": {
"confidence": 0.8250615282513749,
"value": true
},
"dateValidityDelivery": {
"confidence": 0.8432930034987791,
"value": false
},
"photoIsPresent": {
"value": true,
"confidence": 0.978230893611908,
"bbox": {
"topleft": [
0.013986006379127502,
0.17877906560897827
],
"width": 0.3046953082084656,
"height": 0.5566860437393188
}
},
"rfSymbolIsPresent": {
"value": false,
"confidence": 0.8,
"bbox": {}
},
"waveIsPresent": {
"value": true,
"confidence": 0.8196049928665161,
"bbox": {
"topleft": [
0.8461538758128881,
0.20348837971687317
],
"width": 0.05994005873799324,
"height": 0.19622093439102173
}
},
"initialsIsPresent": {
"value": true,
"confidence": 0.8698996305465698,
"bbox": {
"topleft": [
0.2627372667193413,
0.19040697440505028
],
"width": 0.039960041642189026,
"height": 0.04505813866853714
}
},
"globalStatus": {
"value": false,
"confidence": 0.30000000000000004
}
}
}
]
},
Additional information
Loaded scans must pass prerequisites
To provide a qualitative service and a comprehensive data capture, every picture, scan, or document sent to our API must comply with determined prerequisites which can be found on this page
API limitations
- Maximum size : 5 MB
- Maximum number of calls per minute : 10 calls
Updated about 1 year ago
Ready to process document bundles ? See our API Reference documentation for more details