Multi Receipts Detector OCR
Automatically extract the position from multiple Receipts on documents.
Mindee’s Multi Receipts Detector OCR API uses deep learning to automatically, accurately, and instantaneously parse your receipt coordinates. In under a second, the API extracts a set of data from your PDFs or photos of any document showing multiple receipts, including:
- Receipt Position by Bounding Box
It can be easily combined with Mindee's Receipts and Financial Documents OCR API to provide an end to end workflow from detecting to extracting key information on receipts.
Set up the API
Before making any API calls, you need to have created your API key.
- You'll need a document including one or multiple receipts. You can use the sample document provided below.
![](https://files.readme.io/1dd39d3-x_receipts.jpg)
- Access your API by clicking on the Multi Receipts Detector card in the Utilities
![](https://files.readme.io/c73e284-multi-receipts-doc.png)
- From the left navigation, go to documentation > API Reference, you'll find sample code in popular languages and command line.
curl -X POST \\
https://api.mindee.net/v1/products/mindee/multi_receipts_detector/v1/predict \\
-H 'Authorization: Token my-api-key-here' \\
-H 'content-type: multipart/form-data' \\
-F document=@/path/to/your/file.png
import json
import requests
api_key = "my-api-key-here"
account = "mindee"
endpoint = "multi_receipts_detector"
version = "1.0"
url = f"https://api.mindee.net/v1/products/{account}/{endpoint}/v{version}/predict"
with open("/path/to/the/file.ext", "rb") as file_handle:
files = {"document": file_handle}
headers = {"Authorization": f"Token {api_key}"}
response = requests.post(url, files=files, headers=headers)
json_response = response.json()
if not response.ok:
raise RuntimeError(json_response["api_request"]["error"])
print(json.dumps(json_response["document"], indent=2))
// works for NODE > v10
const axios = require("axios");
const fs = require("fs");
const FormData = require("form-data");
const apiKey = "my-api-key-here";
const account = "mindee";
const endpoint = "multi_receipts_detector";
const version = "1.0";
async function makeRequest(filePath) {
let data = new FormData();
data.append("document", fs.createReadStream(filePath));
const config = {
method: "POST",
url: `https://api.mindee.net/v1/products/${account}/${endpoint}/v${version}/predict`,
headers: {
Authorization: `Token ${apiKey}`,
...data.getHeaders()
},
data
}
try {
let response = await axios(config)
console.log(response.data);
} catch (err) {
console.error(err);
process.exit(1);
}
}
makeRequest("/path/to/the/file.ext");
require 'uri'
require 'net/http'
require 'net/https'
api_key = "my-api-key-here"
account = "mindee"
endpoint = "multi_receipts_detector"
version = "1.0"
url = URI("https://api.mindee.net/v1/products/#{account}/#{endpoint}/v#{version}/predict")
file = '/path/to/the/file.ext'
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request['Authorization'] = "Token #{api_key}"
request.set_form([['document', File.open(file)]], 'multipart/form-data')
response = http.request(request)
if !response.kind_of? Net::HTTPSuccess
raise response.msg
end
puts response.read_body
<form onsubmit="mindeeSubmit(event)" >
<input type="file" id="my-file-input" name="file" />
<input type="submit" />
</form>
<script type="text/javascript">
const mindeeSubmit = (evt) => {
evt.preventDefault()
let myFileInput = document.getElementById('my-file-input');
let myFile = myFileInput.files[0]
if (!myFile) { return }
let data = new FormData();
data.append("document", myFile, myFile.name);
let xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "https://api.mindee.net/v1/products/mindee/multi_receipts_detector/v1/predict");
xhr.setRequestHeader("Authorization", "Token my-api-key-here");
xhr.send(data);
}
</script>
using Mindee;
using Mindee.Input;
using Mindee.Http;
using Mindee.Parsing;
string apiKey = "my-api-key-here";
string filePath = "/path/to/the/file.ext";
// Construct a new client
MindeeClient mindeeClient = new MindeeClient(apiKey);
// Load an input source as a path string
// Other input types can be used, as mentioned in the docs
var inputSource = new LocalInputSource(filePath);
// Set the endpoint configuration
CustomEndpoint myEndpoint = new CustomEndpoint(
endpointName: "multi_receipts_detector",
accountName: "mindee",
version: "1.0"
);
var response = await mindeeClient
.ParseAsync(inputSource, myEndpoint);
// Print a summary of the predictions
System.Console.WriteLine(response.Document.ToString());
// Print the document-level predictions
// System.Console.WriteLine(response.Document.Inference.Prediction.ToString());
import com.mindee.MindeeClient;
import com.mindee.input.LocalInputSource;
import com.mindee.parsing.common.PredictResponse;
import com.mindee.product.custom.CustomV1;
import com.mindee.http.Endpoint;
import java.io.File;
import java.io.IOException;
public class SimpleMindeeClient {
public static void main(String[] args) throws IOException {
String apiKey = "my-api-key-here";
String filePath = "/path/to/the/file.ext";
// Init a new client
MindeeClient mindeeClient = new MindeeClient(apiKey);
// Load a file from disk
LocalInputSource inputSource = new LocalInputSource(new File(filePath));
// Configure the endpoint
Endpoint endpoint = new Endpoint(
"multi_receipts_detector",
"mindee",
"1.0"
);
// Parse the file
PredictResponse<CustomV1> response = mindeeClient.parse(
inputSource,
endpoint
);
// Print a summary of the response
System.out.println(response.toString());
// Print a summary of the predictions
// System.out.println(response.getDocument().toString());
// Print the document-level predictions
// System.out.println(response.getDocument().getInference().getPrediction().toString());
// Print the page-level predictions
// response.getDocument().getInference().getPages().forEach(
// page -> System.out.println(page.toString())
// );
}
}
<?php
// cURL install check
if (!function_exists('curl_init')) {
exit("cURL isn't installed for " . phpversion());
}
$API_KEY = 'my-api-key-here';
$FILE_PATH = '/path/to/my/file.pdf';
$MIME_TYPE = 'application/pdf'; // change according to the file type
$ACCOUNT = 'mindee';
$VERSION = '1.0';
$ENDPOINT = 'multi_receipts_detector';
// Open a cURL session to send the document
$ch = curl_init();
// Setup headers
$headers = array(
"Authorization: Token $API_KEY"
);
// Add our file to the request
$data = array(
"document" => new CURLFile(
$FILE_PATH,
$MIME_TYPE,
substr($FILE_PATH, strrpos($FILE_PATH, "/") + 1)
)
);
// URL for a prediction
$url = "https://api.mindee.net/v1/products/$ACCOUNT/$ENDPOINT/v$VERSION/predict";
$options = array(
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POSTFIELDS => $data,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_RETURNTRANSFER => true
);
// Set all options for the cURL request
curl_setopt_array(
$ch,
$options
);
// Execute the request & extract the query content into a variable
$json = curl_exec($ch);
// Close the cURL session
curl_close($ch);
// Store the response as an array to allow for easier manipulations
$result = json_decode($json, true);
// Print the content of the document as raw json
echo json_encode($result, JSON_PRETTY_PRINT);
- Replace my-api-key-here with your new API key, or use the "select an API key" feature and it will be filled automatically.
- Copy and paste the sample code of your desired choice in your application, code environment or terminal.
- Replace
/path/to/my/file
with the path to your receipt.
Always remember to replace your API key!
- Run your code. You will receive a JSON response with the receipt details.
API Response
Here is the full JSON response you get when you call the API:
{
"api_request": {
"error": {},
"resources": [
"document"
],
"status": "success",
"status_code": 201,
"url": "https://api.mindee.net/v1/products/mindee/multi_receipts_detector/v1/predict"
},
"document": {
"id": "c68d69b3-3855-40b6-8dae-f53fd6198800",
"inference": {
"extras": {},
"finished_at": "2023-05-06T16:37:29",
"pages": [
{
"extras": {},
"id": 0,
"orientation": {
"value": 0
},
"prediction": {...}
}
],
"prediction": {...},
"processing_time": 1.755,
"started_at": "2023,-05-06T16:37:28"
},
"is_rotation_applied": true,
"n_pages": 1,
"name": "sample_receipt.jpg"
}
}
You can find the prediction within the prediction
key found in two locations:
- In
document > inference > prediction
for document-level predictions: it contains the different fields extracted at the document level, meaning that for multi-pages PDFs, we reconstruct a single List of Receipts object using all the pages. - In
document > inference > pages[ ] > prediction
for page-level predictions: it gives the prediction for each page independently. With images, there is only one element on this array, but with PDFs, you can find the extracted data for each PDF page.
Each predicted field may contain one or several values:
- a
confidence
score - a
bounding_box
highlighting the information location - a
page_id
where the information was found (document level only)
{
"extras": {},
"finished_at": "2023-08-30T09:04:43.856494",
"is_rotation_applied": true,
"pages": [
{
"extras": {},
"id": 0,
"orientation": {
"value": 0
},
"prediction": {
"orientation": {
"confidence": 0.69,
"degrees": 0
},
"receipts": [
{
"bounding_box": [
[
0.016,
0.538
],
[
0.114,
0.538
],
[
0.114,
0.783
],
[
0.016,
0.783
]
],
"confidence": 1
},
{
"bounding_box": [
[
0.156,
0.389
],
[
0.284,
0.389
],
[
0.284,
0.843
],
[
0.156,
0.843
]
],
"confidence": 1
},
{
"bounding_box": [
[
0.337,
0.381
],
[
0.466,
0.381
],
[
0.466,
0.765
],
[
0.337,
0.765
]
],
"confidence": 1
},
{
"bounding_box": [
[
0.491,
0.296
],
[
0.617,
0.296
],
[
0.617,
0.861
],
[
0.491,
0.861
]
],
"confidence": 1
},
{
"bounding_box": [
[
0.684,
0.294
],
[
0.827,
0.294
],
[
0.827,
0.756
],
[
0.684,
0.756
]
],
"confidence": 1
},
{
"bounding_box": [
[
0.87,
0.435
],
[
0.971,
0.435
],
[
0.971,
0.723
],
[
0.87,
0.723
]
],
"confidence": 1
}
]
}
}
],
"prediction": {
"receipts": [
{
"bounding_box": [
[
0.016,
0.538
],
[
0.114,
0.538
],
[
0.114,
0.783
],
[
0.016,
0.783
]
],
"confidence": 1,
"page_id": 0
},
{
"bounding_box": [
[
0.156,
0.389
],
[
0.284,
0.389
],
[
0.284,
0.843
],
[
0.156,
0.843
]
],
"confidence": 1,
"page_id": 0
},
{
"bounding_box": [
[
0.337,
0.381
],
[
0.466,
0.381
],
[
0.466,
0.765
],
[
0.337,
0.765
]
],
"confidence": 1,
"page_id": 0
},
{
"bounding_box": [
[
0.491,
0.296
],
[
0.617,
0.296
],
[
0.617,
0.861
],
[
0.491,
0.861
]
],
"confidence": 1,
"page_id": 0
},
{
"bounding_box": [
[
0.684,
0.294
],
[
0.827,
0.294
],
[
0.827,
0.756
],
[
0.684,
0.756
]
],
"confidence": 1,
"page_id": 0
},
{
"bounding_box": [
[
0.87,
0.435
],
[
0.971,
0.435
],
[
0.971,
0.723
],
[
0.87,
0.723
]
],
"confidence": 1,
"page_id": 0
}
]
},
"processing_time": 0.672,
"product": {
"features": [
"receipts"
],
"name": "mindee/multi_receipts_detector",
"type": "standard",
"version": "1.0"
},
"started_at": "2023-08-30T09:04:43.184661"
}
Extracted data
Using the above example the following are the basic fields that can be extracted.
List of Receipts
- receipts: This field outputs the coordinates for each receipt detected.
{
"receipts": [
{
"bounding_box": [
[
0.016,
0.538
],
[
0.114,
0.538
],
[
0.114,
0.783
],
[
0.016,
0.783
]
],
"confidence": 1,
"page_id": 0
},
{
"bounding_box": [
[
0.156,
0.389
],
[
0.284,
0.389
],
[
0.284,
0.843
],
[
0.156,
0.843
]
],
"confidence": 1,
"page_id": 0
},
{
"bounding_box": [
[
0.337,
0.381
],
[
0.466,
0.381
],
[
0.466,
0.765
],
[
0.337,
0.765
]
],
"confidence": 1,
"page_id": 0
},
{
"bounding_box": [
[
0.491,
0.296
],
[
0.617,
0.296
],
[
0.617,
0.861
],
[
0.491,
0.861
]
],
"confidence": 1,
"page_id": 0
},
{
"bounding_box": [
[
0.684,
0.294
],
[
0.827,
0.294
],
[
0.827,
0.756
],
[
0.684,
0.756
]
],
"confidence": 1,
"page_id": 0
},
{
"bounding_box": [
[
0.87,
0.435
],
[
0.971,
0.435
],
[
0.971,
0.723
],
[
0.87,
0.723
]
],
"confidence": 1,
"page_id": 0
}
]
}
Questions?
Join our Slack
Updated 6 months ago