OCR For Business
AI-powered OCR technology by Shufti Pro helps businesses save operational costs by extracting relevant information from documents in real-time with an accuracy of up to 90%. The instant image-to-text OCR supports multilingual documents and offers global coverage. Shufti Pro’s intelligent OCR services provide businesses with optimized data extraction.
The Business OCR ‘service call’ is performed independently without including other services.
Ocr for Business includes two parts:
- Training of the Model
- Data extraction using Trained models
Training of the Model
For training of the model client needs to follow these steps in backoffice under section OCR FOR BUSINESS:
- Upload sample document(s) to train the model.
- Select and name the data fields that the client wishes to extract from that document.
- Provide a name to the model and train it.
Once the model is trained the client can start data extraction right away or test the trained model in the backoffice.

Data extraction using Trained models
For data extraction clients need to send the API request to the server with the following parameters:
Parameters | Description |
---|---|
model_name | Required: Yes Type: string A valid model name provided by the client during the model training phase. Example: (invoice_sales) |
proof | Required: Yes Type: string Image Format: JPG, JPEG, PNG, PDF Maximum image size: 16 MB |
In response to API call client will receive JSON response with event of request.received and Shufti Pro will extract required data and send the extracted data to provided callback url (The data is also updated in the client’s backoffice. The client can access that data anytime).

- Http
- Javascript
- PHP
- Python
- Ruby
- Java
- cURL
- C#
- Go
//POST /service/ocr_for_business/extraction HTTP/1.1
//Host: api.shuftipro.com
//Content-Type: application/json
//Authorization: Basic NmI4NmIyNzNmZjM0ZmNlMTlkNmI4WJRTUxINTJHUw==
//replace "Basic" with "Bearer in case of Access Token"
{
"reference" : "1234567",
"business_ocr" : {
"model_name" : "invoice_sales",
"proof":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII="
}
}
let payload = {
reference : `SP_REQUEST_${Math.random()}`,
callback_url : "https://yourdomain.com/profile/sp-notify-callback",
country : "GB",
language : "EN"
}
//get proof base64
convertImgToBase64URL('https://raw.githubusercontent.com/shuftipro/RESTful-API-v1.3/master/assets/real-id-card.jpg').then(response=>{
//Use this key if you want to perform document verification with OCR
payload['business_ocr'] = {
model_name : 'invoice_sales',
proof : response
}
//Use your Shufti Pro account client id and secret key
var token = btoa("YOUR_CLIENT_ID:YOUR_SECRET_KEY"); //BASIC AUTH TOKEN
// if Access Token
//var token = "YOUR_ACCESS_TOKEN";
//Dispatch request via fetch API or with whatever else which best suits for you
fetch('https://api.shuftipro.com/service/ocr_for_business/extraction',
{
method : 'post',
headers : {
'Accept' : 'application/json',
'Content-Type' : 'application/json',
'Authorization' : 'Basic ' +token // if access token then replace "Basic" with "Bearer"
},
body: JSON.stringify(payload)
})
.then(function(response) {
return response.json();
}).then(function(data) {
console.log(data)
return data;
});
})
/*METHOD USED TO Get image BASE 64 string*/
function convertImgToBase64URL(url){
return new Promise(function(resolve, reject) {
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function(){
var canvas = document.createElement('CANVAS'),
ctx = canvas.getContext('2d'), dataURL;
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img, 0, 0);
dataURL = canvas.toDataURL('image/jpeg');
resolve(dataURL);
canvas = null;
};
img.src = url;
})
}
<?php
$url = 'https://api.shuftipro.com/service/ocr_for_business/extraction';
//Your Shufti Pro account Client ID
$client_id = 'YOUR-CLIENT-ID';
//Your Shufti Pro account Secret Key
$secret_key = 'YOUR-SECRET-KEY';
//OR Access Token
//$access_token = 'YOUR-ACCESS-TOKEN';
$verification_request = [
'reference' => 'ref-'.rand(4,444).rand(4,444),
'country' => 'GB',
'language' => 'EN',
'email' => '[email protected]',
'callback_url' => 'https://yourdomain.com/profile/notifyCallback',
];
//Use this key if you want to perform OCR For business service
$verification_request['business_ocr'] =[
'model_name' => 'invoice_sales',
'proof' => base64_encode(file_get_contents('https://raw.githubusercontent.com/shuftipro/RESTful-API-v1.3/master/assets/real-id-card.jpg'))
];
$auth = $client_id.":".$secret_key; // remove this in case of Access Token
$headers = ['Content-Type: application/json'];
// if using Access Token then add it into headers as mentioned below otherwise remove access token
// array_push($headers, 'Authorization: Bearer ' . $access_token);
$post_data = json_encode($verification_request);
//Calling Shufti Pro request API using curl
$response = send_curl($url, $post_data, $headers, $auth); // remove $auth in case of Access Token
//Get Shufti Pro API Response
$response_data = $response['body'];
//Get Shufti Pro Signature
$exploded = explode("\n", $response['headers']);
// Get Signature Key from Hearders
$sp_signature = null;
foreach ($exploded as $key => $value) {
if (strpos($value, 'signature: ') !== false || strpos($value, 'Signature: ') !== false) {
$sp_signature=trim(explode(':', $exploded[$key])[1]);
break;
}
}
//Calculating signature for verification
// calculated signature functionality cannot be implement in case of access token
$calculate_signature = hash('sha256',$response_data.$secret_key);
$decoded_response = json_decode($response_data,true);
$event_name = $decoded_response['event'];
if($event_name == 'request.received'){
if($sp_signature == $calculate_signature){
echo "Response :" . $response_data;
}else{
echo "Invalid signature :" . $response_data;
}
}else{
echo "Error :" . $response_data;
}
function send_curl($url, $post_data, $headers, $auth){ // remove $auth in case of Access Token
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_USERPWD, $auth); // remove this in case of Access Token
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); // remove this in case of Access Token
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$html_response = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($html_response, 0, $header_size);
$body = substr($html_response, $header_size);
curl_close($ch);
return ['headers' => $headers,'body' => $body];
}
?>
import requests, base64, json, hashlib
from random import randint
'''
Python 2
--------
import urllib2
Python 3
--------
import urllib.request
urllib.request.urlopen(url).read()
'''
url = 'https://api.shuftipro.com/service/ocr_for_business/extraction'
# Your Shufti Pro account Client ID
client_id = 'YOUR-CLIENT-ID'
# Your Shufti Pro account Secret Key
secret_key = 'YOUR-SECRET-KEY'
# OR Access Token
# access_token = 'YOUR-ACCESS-TOKEN';
verification_request = {
'reference' : 'ref-{}{}'.format(randint(1000, 9999), randint(1000, 9999)),
'country' : 'GB',
'language' : 'EN',
'email' : '[email protected]',
'callback_url' : 'https://yourdomain.com/profile/notifyCallback'
}
# Use this key if you want to perform OCR For Business service
verification_request['business_ocr'] = {
'model_name' : 'invoice_sales',
'proof' : base64.b64encode(urllib2.urlopen('https://raw.githubusercontent.com/shuftipro/RESTful-API-v1.3/master/assets/real-id-card.jpg').read()).decode(),
}
# Calling Shufti Pro request API using python requests
auth = '{}:{}'.format(client_id, secret_key)
b64Val = base64.b64encode(auth.encode()).decode()
# if access token
# b64Val = access_token
# replace "Basic with "Bearer" in case of Access Token
response = requests.post(url,
headers={"Authorization": "Basic %s" % b64Val, "Content-Type": "application/json"},
data=json.dumps(verification_request))
# Calculating signature for verification
# calculated signature functionality cannot be implement in case of access token
calculated_signature = hashlib.sha256('{}{}'.format(response.content.decode(), secret_key).encode()).hexdigest()
# Get Shufti Pro Signature
sp_signature = response.headers.get('Signature','')
# Convert json string to json object
json_response = json.loads(response.content)
# Get event returned
event_name = json_response['event']
print (json_response)
if event_name == 'request.received':
if sp_signature == calculated_signature:
print ('Verification Response: {}'.format(response.content))
else:
print ('Invalid signature: {}'.format(response.content))
require 'uri'
require 'net/http'
require 'base64'
require 'json'
require 'open-uri'
url = URI("https://api.shuftipro.com/service/ocr_for_business/extraction")
# Your Shufti Pro account Client ID
CLIENT_ID = "YOUR-CLIENT-ID"
# Your Shufti Pro account Secret Key
SECRET_KEY = "YOUR-SECRET-KEY"
# if access token
# ACCESS_TOKEN = "YOUR-ACCESS-TOKEN"
SAMPLE_DOCUMENT_IMAGE = "https://raw.githubusercontent.com/shuftipro/RESTful-API-v1.3/master/assets/real-id-card.jpg"
verification_request = {
reference: "Ref-"+ (0...8).map { (65 + rand(26)).chr }.join,
callback_url: "https://yourdomain.com/profile/notifyCallback",
email: "[email protected]",
country: "GB",
language: "EN"
}
# Use this key if you want to perform OCR For Business service
verification_request["business_ocr"] = {
model_name: 'invoice_sales',
proof: Base64.encode64(open(SAMPLE_DOCUMENT_IMAGE).read),
}
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
header_auth = Base64.strict_encode64("#{CLIENT_ID}:#{SECRET_KEY}")
# if Access Token
# header_auth = ACCESS_TOKEN
request["Content-Type"] = "application/json"
request["Authorization"] = "Basic #{header_auth}" # replace "Basic" with "Bearer" in case of access token
request.body = verification_request.to_json
response = http.request(request)
response_headers = response.instance_variable_get("@header")
response_data = response.read_body
sp_signature = !(response_headers['signature'].nil?) ? response_headers['signature'].join(',') : ""
# calculated signature functionality cannot be implement in case of access token
calculated_signature = Digest::SHA256.hexdigest response_data + SECRET_KEY
if sp_signature == calculated_signature
puts response_data
else
puts "Invalid signature"
end
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import javax.net.ssl.HttpsURLConnection;
public class Main {
public static void main(String[] args) throws Exception {
String url = "https://api.shuftipro.com/service/ocr_for_business/extraction";
String CLIENT_ID = "CLIENT_ID";
String SECRET_KEY = "SECRET_KEY";
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
// Add request header
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json");
String basicAuth = "Basic " + Base64.getEncoder().encodeToString((CLIENT_ID + ":" + SECRET_KEY).getBytes(StandardCharsets.UTF_8));
con.setRequestProperty("Authorization", basicAuth);
String payload = "{\n \"reference\" : \"1234567\",\n \"business_ocr\" : {\n\t \t\"model_name\" : \"invoice_sales\",\n \t\t\"proof\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII=\"\n }\n}";
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(payload);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Payload : " + payload);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
System.out.println(in.toString());
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// Print the response
System.out.println(response.toString());
}
}
curl --location --request POST 'https://api.shuftipro.com//service/ocr_for_business/extraction' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic NmI4NmIyNzNmZjM0ZmNlMTlkNmI4WJRTUxINTJHUw==' \
--data-raw '{
"reference" : "1234567",
"business_ocr" : {
"model_name" : "invoice_sales",
"proof":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII="
}
}'
var client = new RestClient("https://api.shuftipro.com//service/ocr_for_business/extraction");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "Basic NmI4NmIyNzNmZjM0ZmNlMTlkNmI4WJRTUxINTJHUw==");
var body = @"{" + "\n" +
@" ""reference"" : ""1234567""," + "\n" +
@" ""business_ocr"" : {" + "\n" +
@" ""model_name"" : ""invoice_sales""," + "\n" +
@" ""proof"":""data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII=""" + "\n" +
@" }" + "\n" +
@"}";
request.AddParameter("application/json", body, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
package main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "https://api.shuftipro.com//service/ocr_for_business/extraction"
method := "POST"
payload := strings.NewReader(`{
"reference" : "1234567",
"business_ocr" : {
"model_name" : "invoice_sales",
"proof":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII="
}
}`)
client := &http.Client {
}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", "Basic NmI4NmIyNzNmZjM0ZmNlMTlkNmI4WJRTUxINTJHUw==")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
{
"reference": "17374217",
"event": "request.received",
"email": "[email protected]",
"country": "UK"
}
//Content-Type: application/json
//Signature: NmI4NmIyNzNmZjM0ZmNl
{
"reference": "17374217",
"event": "verification.accepted",
"email": "[email protected]",
"country" : "GB",
"verification_result": {},
"verification_data": {
"business_ocr": {
"last_name": "Doe",
"first_name": "John",
"issue_date": "2018-01-31",
"expiry_date": "2028-01-30",
"nationality": "BRITSH CITIZEN",
"gender": "M",
"place_of_birth": "BRISTOL",
"document_number": "GB1234567",
}
},
"info": {
"agent": {
"is_desktop": true,
"is_phone": false,
"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
"device_name": "Macintosh",
"browser_name": "",
"platform_name": "OS X - 10_14_0"
},
"geolocation": {
"host": "212.103.50.243",
"ip": "212.103.50.243",
"rdns": "212.103.50.243",
"asn": "9009",
"isp": "M247 Ltd",
"country_name": "Germany",
"country_code": "DE",
"region_name": "Hesse",
"region_code": "HE",
"city": "Frankfurt am Main",
"postal_code": "60326",
"continent_name": "Europe",
"continent_code": "EU",
"latitude": "50.1049",
"longitude": "8.6295",
"metro_code": "",
"timezone": "Europe/Berlin"
}
},
}