Invoice OCR
Automatically extract data from unstructured invoices
Mindee’s Invoice OCR API uses deep learning to automatically, accurately, and instantaneously parse invoices in your applications. It takes the API a few seconds to extract data from your PDFs or photos of invoices. The API extracts data such as:
- Line items
- Due date
- Payment date
- Invoice date
- Invoice number
- Purchase order
- Reference numbers
- Locale & currency
- Payment details (IBAN, Swift, Bic, Account number...)
- Supplier company registrations (SIRET, EIN, VAT number...)
- Supplier name
- Total tax
- Taxes details
- Total amount including taxes
- Total net amount (excluding taxes)
- Customer address
- Shipping address
- Billing address
- Customer company registrations
- Customer name
- Supplier address
Supported Countries
We officially support the following countries, which doesn't prevent you to use the API for invoices from different locations: you may get the country-specific data like taxes.
North America
United States & Canada
Europe
Austria, Belgium, Croatia, Czech Republic, Denmark, Estonia, Finland, France, Germany, Hungary, Iceland, Ireland, Italy, Latvia, Luxembourg, Monaco, Netherlands, Norway, Poland, Portugal, Romania, Slovakia, Slovenia, Spain, Sweden, Switzerland & United Kingdom
Set up the API
Before making any API calls, you need to have created your API key.
-
You'll need to get an invoice. This can be a recently received invoice or you can google for free invoice samples that you can download to test with. Alternatively, you can use the sample invoice provided below.
-
Access your Invoice API by clicking on the Invoice card in the APIs Store.
- From the left navigation, go to documentation > API reference, you'll find sample code in popular languages and command line.
- You can switch from synchronous to asynchronous to retrieve the sample code adapted to your use case.
curl -X POST \
https://api.mindee.net/v1/products/mindee/invoices/v4/predict \
-H 'Authorization: Token my-api-key-here' \
-F document=@/path/to/your/file.png
import requests
url = "https://api.mindee.net/v1/products/mindee/invoices/v4/predict"
with open("/path/to/my/file", "rb") as myfile:
files = {"document": myfile}
headers = {"Authorization": "Token my-api-key-here"}
response = requests.post(url, files=files, headers=headers)
print(response.text)
// works for NODE > v10
const axios = require('axios');
const fs = require("fs");
const FormData = require('form-data')
async function makeRequest() {
let data = new FormData()
data.append('document', fs.createReadStream('./file.jpg'))
const config = {
method: 'POST',
url: 'https://api.mindee.net/v1/products/mindee/invoices/v4/predict',
headers: {
'Authorization':'Token my-api-key-here',
...data.getHeaders()
},
data
}
try {
let response = await axios(config)
console.log(response.data);
} catch (error) {
console.log(error)
}
}
makeRequest()
# tested with Ruby 2.5
require 'uri'
require 'net/http'
require 'net/https'
require 'mime/types'
url = URI("https://api.mindee.net/v1/products/mindee/invoices/v4/predict")
file = "/path/to/your/file.png"
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Token my-api-key-here'
request.set_form([['document', File.open(file)]], 'multipart/form-data')
response = http.request(request)
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/invoices/v4/predict");
xhr.setRequestHeader("Authorization", "Token my-api-key-here");
xhr.send(data);
}
</script>
- 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, terminal etc.
- Replace
/path/to/your/file/png
with the path to your invoice.
Always remember to replace your API key!
- Run your code. You will receive a JSON response with the invoice details.
API Response
Below is the full sample JSON response you get when you call the API. Since the response is quite verbose, we will walk through the fields section by section.
{
"api_request": {
"error": {},
"resources": [
"document"
],
"status": "success",
"status_code": 201,
"url": "http://api.mindee.net/v1/products/mindee/invoices/v4/predict"
},
"document": {
"id": "ecdbe7bd-1037-47a5-87a8-b90d49475a1f",
"name": "sample_invoce.jpeg",
"n_pages": 1,
"is_rotation_applied": true,
"inference": {
"started_at": "2021-05-06T16:37:28",
"finished_at": "2021-05-06T16:37:29",
"processing_time": 1.125,
"pages": [
{
"id": 0,
"orientation": {"value": 0},
"prediction": { .. },
"extras": {}
}
],
"prediction": { .. },
"extras": {}
}
}
}
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 invoice 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
polygon
highlighting the information location - a
page_id
where the information was found (document level only)
{
"prediction": {
"supplier_company_registrations": [
{
"confidence": 0.99,
"page_id": 0,
"polygon": [[ 0.515, 0.962 ], [ 0.59, 0.962 ], [ 0.59, 0.973 ], [ 0.515, 0.973 ]],
"type": "SIRET",
"value": "XXX81125600010"
},
{
"confidence": 0.99,
"page_id": 0,
"polygon": [[ 0.658, 0.963 ], [ 0.729, 0.963 ], [ 0.729, 0.973 ], [ 0.658, 0.973 ]],
"type": "VAT NUMBER",
"value": "FR44837811XXX"
}
],
"customer_name": {
"confidence": 0.84,
"page_id": 0,
"polygon": [[0.035, 0.284], [0.098, 0.284], [0.098, 0.296], [0.035, 0.296]],
"value": "JIRO DOI",
"raw_value":"Jiro Doi"
},
"customer_address": {
"confidence": 0.3,
"page_id": 0,
"polygon": [[0.035, 0.304], [0.214, 0.304], [0.214, 0.353], [0.035, 0.353]],
"value": "1954 Bloon Street West Toronto, ON, M6P 3K9 Canada"
},
"billing_address": {
"confidence": 0.3,
"page_id": 0,
"polygon": [[0.035, 0.304], [0.214, 0.304], [0.214, 0.353], [0.035, 0.353]],
"value": "1954 Bloon Street West Toronto, ON, M6P 3K9 Canada"
},
"shipping_address": {
"confidence": 0.3,
"page_id": 0,
"polygon": [[0.035, 0.304], [0.214, 0.304], [0.214, 0.353], [0.035, 0.353]],
"value": "1954 Bloon Street West Toronto, ON, M6P 3K9 Canada"
},
"customer_company_registrations":[
{
"confidence": 0.84,
"page_id": 0,
"polygon": [[0.113, 0.251], [0.206, 0.251], [0.206, 0.266], [0.113, 0.266]],
"type": "TIN",
"value": "736952710"
}
],
"date": {
"confidence": 0.99,
"page_id": 0,
"polygon": [[0.842, 0.305], [0.931, 0.305], [0.931, 0.319], [0.842, 0.319]],
"value": "2018-09-25"
},
"document_type": {
"value": "INVOICE"
},
"due_date": {
"confidence": 0.93,
"page_id": 0,
"polygon": [[0.84, 0.326], [0.943, 0.326], [0.943, 0.34], [0.84, 0.34]],
"is_computed": False,
"value": "2018-09-25"
},
"payment_date": {
"confidence": 0.93,
"page_id": 0,
"polygon": [[0.84, 0.326], [0.943, 0.326], [0.943, 0.34], [0.84, 0.34]],
"is_computed": False,
"value": "2018-09-25"
},
"invoice_number": {
"confidence": 0.99,
"page_id": 0,
"polygon": [[0.843, 0.265], [0.861, 0.265], [0.861, 0.28], [0.843, 0.28]],
"value": "14"
},
"po_number": {
"confidence": 0.99,
"page_id": 0,
"polygon": [[0.843, 0.265], [0.861, 0.265], [0.861, 0.28], [0.843, 0.28]],
"value": "36"
},
"reference_numbers": [
{
"confidence": 0.91,
"polygon": [[0.84, 0.284],[0.914, 0.284],[0.914, 0.298],[0.84, 0.298]],
"value": "AD29094"
}
],
"locale": {
"confidence": 0.93,
"currency": "CAD",
"language": "en"
},
"orientation": {
"confidence": 0.99,
"degrees": 0
},
"supplier_payment_details": [
{
"account_number": "XXXX",
"confidence": 0.95,
"iban": "XXXX",
"page_id": 0,
"polygon": [[0.035, 0.304], [0.214, 0.304], [0.214, 0.353], [0.035, 0.0353]],
"routing_number": "XXX",
"swift": "XXX"
}
],
"supplier_name": {
"confidence": 0.72,
"page_id": 0,
"polygon": [[0.164, 0.087], [0.4, 0.087], [0.4, 0.147], [0.164, 0.147]],
"value": "TURNPIKE DESIGNS CO.",
"raw_value": "Turnpike Designs Co."
},
"supplier_address": {
"confidence": 0.49,
"page_id": 0,
"polygon": [[0.756, 0.128], [0.964, 0.128], [0.964, 0.162], [0.756, 0.162]],
"value": "156 University Ave, Toronto ON, Canada M5H 2H7"
},
"taxes":[
{
"confidence": 0.76,
"page_id": 0,
"polygon": [[0.785, 0.745], [0.965, 0.745], [0.965, 0.758], [0.785, 0.758]],
"rate": 8,
"value": 193.2,
"base": 2415.0
}
],
"total_net": {
"confidence": 0,
"page_id": null,
"polygon": [[0.886, 0.839], [0.971, 0.839], [0.971, 0.858], [0.886, 0.858]],
"value": 2608.2
},
"total_amount": {
"confidence": 0.99,
"page_id": 0,
"polygon": [[0.887, 0.84], [0.97, 0.84], [0.97, 0.858], [0.887, 0.858]],
"value": 2608.2
},
"total_tax": {
"confidence": 0.76,
"polygon": [],
"value": 193.2
}
}
}
Depending on the field type specified, additional attributes can be extracted from the invoice object. Using the above invoice example, the following are the basic fields that can be extracted.
- Line items
- Reference numbers
- Invoice Number
- Purchase Order Number
- Customer Information
- Dates
- Locale
- Orientation
- Supplier Information
- Taxes
- Total Amounts
Line items
- line_items: In the JSON response below, we have the list of items included in the body of the invoice. Each item may contain:
- description (String Generic): The description of the item
- product_code (String Generic): the code that identifies the product in the line. It can be a reference number, a product ID, an Article code…
- quantity (number)
- unit_price (number)
- total_amount (number): The line total amount
- tax_amount (number)
- tax_rate (number): Returned in %
{
"line_items": [
{
"confidence": 0.97,
"description": "Platinum web hosting package Down 35mb, Up 100mb",
"polygon": [
[0.035, 0.501],
[0.965, 0.501],
[0.965, 0.537],
[0.035, 0.537]
],
"product_code": null,
"quantity": 1,
"tax_amount": null,
"tax_rate": null,
"total_amount": 65,
"unit_price": 65
},
{
"confidence": 0.97,
"description": "2 page website design Includes basic wireframes, and responsive templates",
"polygon": [
[0.035, 0.562],
[0.964, 0.562],
[0.964, 0.599],
[0.035, 0.599]
],
"product_code": null,
"quantity": 3,
"tax_amount": null,
"tax_rate": null,
"total_amount": 2100,
"unit_price": 2100
},
{
"confidence": 0.96,
"description": "Mobile designs Includes responsive navigation",
"polygon": [
[0.035, 0.626],
[0.964, 0.626],
[0.964, 0.662],
[0.035, 0.662]
],
"product_code": null,
"quantity": 1,
"tax_amount": null,
"tax_rate": null,
"total_amount": 250,
"unit_price": 250
}
]
}
Reference numbers
- reference_numbers: In the JSON response we have a list of variable size with references extracted including PO numbers, reference numbers or more rarely project numbers.
{
"reference_numbers": [
{
"confidence": 1,
"polygon": [
[0.628, 0.374],
[0.703, 0.374],
[0.703, 0.383],
[0.628, 0.383]
],
"value": "PO-00001827"
},
{
"confidence": 1,
"polygon": [
[0.156, 0.901],
[0.211, 0.901],
[0.211, 0.908],
[0.156, 0.908]
],
"value": "1C5H17N"
}
]
}
Invoice Number
- invoice_number : in the JSON response bellow, the value of the Invoice number.
{
"invoice_number": {
"confidence": 0.99,
"page_id": 0,
"polygon": [[0.843,0.265],[0.861,0.265],[0.861,0.28],[0.843,0.28]],
"value": "14"
}
}
Purchase order number
- po_number : in the JSON response bellow, the value of the PO number
{
"po_number": {
"confidence": 0.99,
"page_id": 0,
"polygon": [[0.843,0.265],[0.861,0.265],[0.861,0.28],[0.843,0.28]],
"value": "36"
}
}
Customer Information
- customer_name: In the JSON response, we have the value and the raw_value of the customer name as found on the invoice.
{
"customer_name": {
"confidence": 0.84,
"page_id": 0,
"polygon": [[0.035, 0.284], [0.098, 0.298], [0.098, 0.296], [0.035, 0.296]],
"value": "JIRO DOI",
"raw_value": "Jiro Doi"
}
}
- customer_address: In the JSON response, we have the value of the customer address as found on the invoice.
{
"customer_address": {
"confidence": 0.3,
"page_id": 0,
"polygon": [[0.035, 0.304], [0.214, 0.304], [0.214, 0.353], [0.035, 0.0353]],
"value": "1954 Bloon Street West Toronto, ON, M6P 3K9 Canada"
}
}
- billing_address: In the JSON response, we have the value of the billing address as found on the invoice.
{
"billing_address": {
"confidence": 0.3,
"page_id": 0,
"polygon": [[0.035, 0.304], [0.214, 0.304], [0.214, 0.353], [0.035, 0.0353]],
"value": "1954 Bloon Street West Toronto, ON, M6P 3K9 Canada"
}
}
- shpping_address: In the JSON response, we have the value of the shipping address as found on the invoice.
{
"shipping_address": {
"confidence": 0.3,
"page_id": 0,
"polygon": [[0.035, 0.304], [0.214, 0.304], [0.214, 0.353], [0.035, 0.0353]],
"value": "1954 Bloon Street West Toronto, ON, M6P 3K9 Canada"
}
}
- customer_company_registrations (string): In the JSON response below, we have the list of the customer company identifiers. Each item may contain:
- type (String Generic): The following company registration numbers are supported: VAT NUMBER, SIRET, SIREN, NIF, CF, UID, STNR, HRA/HRB, TIN (includes EIN, FEIN, SSN, ATIN, PTIN, ITIN), RFC, BTW, ABN, UEN, CVR, ORGNR, INN, DPH, GSTIN, COMPANY REGISTRATION NUMBER (UK), KVK, DIC, TAX ID, CIF, GST/HST, COC
- value (String): Value of the company identifier
{
"customer_company_registrations": [
{
"confidence": 0.99,
"page_id": 0,
"polygon": [[ 0.515, 0.962 ], [ 0.59, 0.962 ], [ 0.59, 0.973 ], [ 0.515, 0.973 ]],
"type": "SIRET",
"value": "XXX81125600010"
},
{
"confidence": 0.99,
"page_id": 0,
"polygon": [[ 0.658, 0.963 ], [ 0.729, 0.963 ], [ 0.729, 0.973 ], [ 0.658, 0.973 ]],
"type": "VAT NUMBER",
"value": "FR44837811XXX"
}
]
}
- customer_id: The customer account number or identifier from the supplier.
{
"customer_id": {
"confidence": 0.8,
"page_id": 0,
"polygon": [[0.034, 0.303], [0.213, 0.303], [0.213, 0.354], [0.034, 0.354]],
"value": "ABCD-1234"
}
}
Dates
- invoice date: In the JSON response below, we have the value of the invoice date in an ISO format(yyyy-mm-dd).
{
"date": {
"confidence": 0.99,
"page_id": 0,
"polygon": [[0.84, 0.305], [0.932, 0.305], [0.932, 0.318], [0.84, 0.318]],
"value": "2018-09-25"
}
}
- due_date: In the JSON response below, we have the value of the invoice due date in an ISO format(yyyy-mm-dd).
{
"due_date": {
"confidence": 0.86,
"page_id": 0,
"polygon": [[0.841, 0.323], [0.941, 0.323], [0.941, 0.338], [0.841, 0.338]],
"is_computed": False,
"value": "2018-09-25"
}
}
is_computed
It is set to
True
if thedue_date
is calculated based on payment terms or natural language, andFalse
if it is directly specified as a date in the document
- payment_date: In the JSON response below, we have the value of the invoice due date in an ISO format(yyyy-mm-dd).
{
"due_date": {
"confidence": 0.86,
"page_id": 0,
"polygon": [[0.841, 0.323], [0.941, 0.323], [0.941, 0.338], [0.841, 0.338]],
"is_computed": False,
"value": "2018-09-25"
}
}
is_computed
It is set to
True
if thedue_date
is calculated based on payment terms or natural language, andFalse
if it is directly specified as a date in the document
Locale
- locale: In the JSON response, we have the currency and language found on the invoice.
- language (String): Language code in ISO 639-1 format as seen on the invoice. The following language codes are supported:
ca
,de
,en
,es
,fr
,it
,nl
andpt
. - currency (String): Currency code in ISO 4217 format as seen on the invoice. The following country codes are supported:
USD
,EUR
,GBP
,CAD
,CHF
,AED
,AUD
,BRL
,CNY
,COP
,CZK
,DKK
,GNF
,HKD
,HUF
,JPY
,NOK
,NZD
,PLN
,SEK
,SGD
,XPF
- language (String): Language code in ISO 639-1 format as seen on the invoice. The following language codes are supported:
{
"locale": {
"confidence": 0.94,
"currency": "CAD",
"language": "en"
}
}
Orientation
- orientation: The orientation field is only available at the page level as it describes whether the page image should be rotated to be upright. The rotation value is also conveniently available in the JSON response at:
document > inference > pages [ ] > orientation > value
.
If the page requires rotation for correct display, the orientation field gives a prediction among these 3 possible outputs:- 0 degree: the page is already upright
- 90 degrees: the page must be rotated clockwise to be upright
- 270 degrees: the page must be rotated counterclockwise to be upright
In our example, the receipt doesn't require any rotation.
{
"orientation": {
"confidence": 0.99,
"degrees": 0
}
}
All
polygon
fields across the JSON response are already rotated accordingly!
Supplier Information
- supplier_payment_details: On some invoices, there are many payment details written such as account number, IBAN, routing number, BIC etc. Our Invoice OCR extracts all of them. In the JSON response below, we have the list of the suppliers' payment details, each item contains different fields and they are set to null or filled with the right value depending on the invoice:
{
"supplier_payment_details": [
{
"account_number": "XXXX",
"confidence": 0.95,
"iban": "XXXX",
"page_id": 0,
"polygon": [[0.035, 0.304], [0.214, 0.304], [0.214, 0.353], [0.035, 0.0353]],
"routing_number": "XXX",
"swift": "XXX"
}
]
}
- supplier_company_registrations: List of detected supplier's company registration number. Each company number object contains an extra attribute:
- type (String Generic): The following company registration numbers are supported: VAT NUMBER, SIRET, SIREN, NIF, CF, UID, STNR, HRA/HRB, TIN (includes EIN, FEIN, SSN, ATIN, PTIN, ITIN), RFC, BTW, ABN, UEN, CVR, ORGNR, INN, DPH, GSTIN, COMPANY REGISTRATION NUMBER (UK), KVK, DIC, TAX ID, CIF, GST/HST, COC
- value (String): Value of the company identifier
{
"supplier_company_registrations": [
{
"confidence": 0.99,
"page_id": 0,
"polygon": [[0.515, 0.962], [0.59, 0.962], [0.59, 0.973], [0.515, 0.973]],
"type": "SIRET",
"value": "XXX81125600010"
},
{
"confidence": 0.99,
"page_id": 0,
"polygon": [[0.658, 0.963], [0.729, 0.963], [0.729, 0.973], [0.658, 0.973]],
"type": "VAT",
"value": "FR44837811XXX"
}
]
}
- supplier_name: In the JSON response below, we have the value and the raw_value of the supplier name as written in the invoice.
{
"supplier_name": {
"confidence": 0.11,
"page_id": 0,
"polygon": [[0.165, 0.089], [0.385, 0.089], [0.385, 0.145], [0.165, 0.145]],
"value": "DESIGNS TURNPIKE CO",
"raw_value": "Turnpike Designs Co."
}
}
- supplier_address: In the JSON response, we have the value of the supplier address as found on the invoice.
{
"supplier_address": {
"confidence": 0.49,
"page_id": 0,
"polygon": [[0.756, 0.128], [0.964, 0.128], [0.964, 0.162], [0.756, 0.162]],
"value": "156 University Ave, Toronto ON, Canada M5H 2H7"
}
}
-
supplier_phone_number: in the JSON response the value of the supplier phone number.
-
supplier_email: The e-mail of the supplier or merchant.
-
supplier_website: The website URL of the supplier or merchant.
Taxes
- taxes: In the JSON response below, we have the list of taxes detected in the invoice. Each tax item includes:
- value (number): The tax amount.
- rate (number): The tax rate.
- base (number): The tax base.
{
"taxes": [
{
"confidence": 0.76,
"page_id": 0,
"polygon": [[0.784, 0.744], [0.965, 0.744], [0.965, 0.758], [0.784, 0.758]],
"rate": 8.0,
"value": 193.2,
"base": 2415.0
}
]
}
Total tax
- total_tax: Total tax amount of the purchase.
{
"total_tax": {
"confidence": 0.79,
"page_id": 0,
"polygon": [[0.549, 0.619], [0.715, 0.619], [0.715, 0.64], [0.549, 0.64]],
"value": 193.2
}
}
Total Amounts
- total_amount: In the JSON response below, we have the value of the total amount including taxes.
{
"total_amount": {
"confidence": 0.99,
"page_id": 0,
"polygon": [[0.886, 0.839], [0.971, 0.839], [0.971, 0.858], [0.886, 0.858]],
"value": 2608.2
}
}
- total_net: In the JSON response below, we have the value of the total amount excluding taxes.
{
"total_net": {
"confidence": 0.4,
"page_id": 0,
"polygon": [[0.886, 0.839], [0.971, 0.839], [0.971, 0.858], [0.886, 0.858]],
"value": 2608.2
}
}
Questions?
Join our Slack
Updated about 1 month ago