Codesota · OCR · Invoice & Receipt BenchmarkHome/OCR/Invoice & Receipt
Benchmark · January 2025

Invoice & Receipt OCR.

Independent comparison of 6 OCR models on real invoice and receipt processing. We measure what matters: line-item extraction, totals verification, and structure preservation.

§ 01 · Key Finding

Specialized extractors lead, at a price.

Azure Document Intelligence leads on line-item extraction (94.2%) but costs 7× more than Mistral OCR 3. For simple receipts, Mistral at $2/1000 pages is sufficient. For complex invoices requiring total verification, specialized extractors are worth the cost.

§ 02 · Why Invoices Are Hard

Beyond character accuracy.

General OCR measures character accuracy. Invoice OCR requires semantic understanding: recognizing line items, verifying math, detecting vendor information.

Line-Item Extraction

Parse tabular data into structured rows. Each row needs: description, quantity, unit price, total.

Challenge · Variable column layouts, merged cells, implicit headers

Totals Verification

Extract and validate: subtotal, tax rate, tax amount, and total. Math should check out.

Challenge · Multiple tax rates, discounts, currency symbols

Vendor Detection

Identify vendor name, address, tax ID, and bank details. Crucial for accounting integration.

Challenge · Logos, letterheads, varying formats

§ 03 · Benchmark Results

500 invoices, 12 industries, 8 languages.

Tested on 500 real invoices and receipts across 12 industries and 8 languages.

ModelTypeLine ItemsTotalsVendorStructureCost / 1000
Azure Document IntelligenceSpecialized94.2%98.1%96.5%95.8%$15
Google Document AISpecialized93.8%97.5%95.2%94.6%$15
Claude Sonnet 4VLM91.5%96.2%94.8%92.1%$60
GPT-4VVLM90.8%95.8%93.5%91.4%$75
Mistral OCR 3Expert OCR88.6%92.4%89.2%93.5%$2
DoclingOpen Source82.5%88.2%85.4%86.8%$0

Line Items = correct description, qty, price, total extracted. Totals = subtotal + tax + total correctly parsed and verified. Vendor = name, address, tax ID correctly identified. Structure = table formatting preserved.

§ 04 · Line-Item Extraction

The critical metric.

A line item is only correct if ALL fields match: description, quantity, unit price, and line total.

Common Failure Modes

  • Merged cells: Multi-line descriptions split incorrectly
  • Currency confusion: $1,234.56 vs 1.234,56 EUR
  • Unit variants: "pcs" vs "pieces" vs "units"
  • Discount rows: Negative amounts mishandled

Why Specialized Extractors Win

  • +Pre-trained schemas: Know what invoice fields look like
  • +Table detection: Dedicated table parsing pipelines
  • +Business logic: Validates qty × price = total
  • +Format library: Trained on millions of invoices
§ 05 · Structure Preservation

Headers, tables, math.

Beyond raw text extraction — how well does the model preserve headers, footers, table structures, and the logical organization of the document?

ModelHeadersTablesTax CalcOutput Format
Azure Document IntelligenceExcellentExcellentVerifiedStructured JSON
Google Document AIExcellentExcellentVerifiedStructured JSON
Claude Sonnet 4ExcellentGoodExtractedPrompted JSON
GPT-4VExcellentGoodExtractedJSON Mode
Mistral OCR 3GoodExcellentNoneMarkdown + HTML
DoclingGoodGoodNoneMarkdown/JSON

Tax Calc: "Verified" = model checks math. "Extracted" = values extracted but not validated. "None" = pure OCR, no semantic understanding.

§ 06 · Code Examples

Five integrations.

Mistral OCR 3 (Cost-Effective)

from mistralai import Mistral
import base64
import json

client = Mistral(api_key="your-api-key")

def extract_invoice(image_path):
    with open(image_path, "rb") as f:
        image_data = base64.b64encode(f.read()).decode()

    response = client.ocr.process(
        model="mistral-ocr-2512",
        document={"type": "image", "data": image_data}
    )

    # Parse markdown output for invoice fields
    return response.content

Claude Sonnet 4 (Low Hallucination)

import anthropic
import base64
import json

client = anthropic.Anthropic()

def extract_invoice(image_path):
    with open(image_path, "rb") as f:
        image_data = base64.b64encode(f.read()).decode()

    message = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=4096,
        messages=[{
            "role": "user",
            "content": [
                {"type": "image", "source": {
                    "type": "base64",
                    "media_type": "image/png",
                    "data": image_data
                }},
                {"type": "text", "text": """Extract invoice data as JSON:
{
  "invoice_number": "",
  "date": "",
  "vendor": {"name": "", "address": "", "tax_id": ""},
  "buyer": {"name": "", "address": "", "tax_id": ""},
  "line_items": [{"description": "", "qty": 0, "unit_price": 0, "total": 0}],
  "subtotal": 0,
  "tax_rate": "",
  "tax_amount": 0,
  "total": 0
}"""}
            ]
        }]
    )
    return json.loads(message.content[0].text)

GPT-4V with JSON Mode

from openai import OpenAI
import base64
import json

client = OpenAI()

def extract_invoice(image_path):
    with open(image_path, "rb") as f:
        image_data = base64.b64encode(f.read()).decode()

    response = client.chat.completions.create(
        model="gpt-4o",
        response_format={"type": "json_object"},
        messages=[{
            "role": "user",
            "content": [
                {"type": "image_url", "image_url": {
                    "url": f"data:image/png;base64,{image_data}"
                }},
                {"type": "text", "text": """Extract all invoice data.
Return JSON with: invoice_number, date, vendor, buyer,
line_items (description, qty, unit_price, total),
subtotal, tax_rate, tax_amount, total"""}
            ]
        }]
    )
    return json.loads(response.choices[0].message.content)

Azure Document Intelligence (Specialized)

from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.core.credentials import AzureKeyCredential

client = DocumentAnalysisClient(
    endpoint="your-endpoint",
    credential=AzureKeyCredential("your-key")
)

def extract_invoice(file_path):
    with open(file_path, "rb") as f:
        poller = client.begin_analyze_document(
            "prebuilt-invoice", f
        )
    result = poller.result()

    invoice = result.documents[0]
    return {
        "invoice_number": invoice.fields.get("InvoiceId").value,
        "vendor": invoice.fields.get("VendorName").value,
        "total": invoice.fields.get("InvoiceTotal").value.amount,
        "line_items": [
            {
                "description": item.value.get("Description").value,
                "quantity": item.value.get("Quantity").value,
                "amount": item.value.get("Amount").value.amount
            }
            for item in invoice.fields.get("Items").value
        ]
    }

Docling (Open Source / Self-Hosted)

from docling.document_converter import DocumentConverter
from docling.datamodel.base_models import InputFormat, DocumentFormat

converter = DocumentConverter()

def extract_invoice(file_path):
    result = converter.convert(file_path)
    doc = result.document

    # Docling returns structured document with tables
    tables = []
    for table in doc.tables:
        tables.append({
            "headers": table.columns,
            "rows": [
                {col: row.cells[i].text for i, col in enumerate(table.columns)}
                for row in table.body
            ]
        })

    return {
        "text": doc.export_to_markdown(),
        "tables": tables
    }
§ 07 · Cost Analysis

Per 1,000 invoices.

ModelAPI CostInfra CostTotalNotes
Docling (self-hosted)$0~$5$5GPU compute only
Mistral OCR 3$2$0$2Batch API: $1
Azure / Google$15$0$15Pre-built extractors
Claude Sonnet 4$60$0$60~800 tokens/invoice
GPT-4V$75$0$75~1000 tokens/invoice

At Scale: 100,000 Invoices/Month

Mistral OCR 3
$200/mo
Azure / Google
$1,500/mo
GPT-4V
$7,500/mo
§ 08 · Recommendations

By invoice type.

Simple Receipts

Low

Retail receipts, point-of-sale printouts

Mistral OCR 3
Cost-effective at $2/1000. Good enough for simple line items.

Standard Invoices

Medium

B2B invoices with line items, tax, totals

Azure Document Intelligence
Best line-item accuracy (94.2%) with pre-built invoice extractor.

Complex Multi-Page

High

Multi-page invoices, complex tables

Claude Sonnet 4
Best at understanding context across pages. Lowest hallucination.

International Invoices

High

Non-English, various formats (EU VAT, etc.)

Google Document AI
Strong multilingual support. Handles EU VAT formats.

Handwritten Notes

High

Receipts with handwritten additions

GPT-4V
Best handwriting recognition among VLMs.

Privacy-Sensitive

Variable

Healthcare, legal, financial documents

Docling (self-hosted)
No data leaves your infrastructure. Apache 2.0 license.
§ 09 · Decision Matrix

Quick guide.

High volume (>10,000/month) + Simple receipts

Use Mistral OCR 3. $2/1000 pages. Good table extraction. Parse markdown output with your own post-processing.

Enterprise + Complex invoices + Compliance required

Use Azure Document Intelligence or Google Document AI. Pre-built invoice extractors. SLAs. Audit trails. $15/1000 pages.

Privacy-sensitive + On-premise required

Use Docling self-hosted. Apache 2.0 license. No data leaves your infrastructure. 82.5% line-item accuracy.

Complex multi-page + Need reliability over speed

Use Claude Sonnet 4. Lowest hallucination rate (0.09%). Best for documents where inventing data is unacceptable.

Mixed content + Handwritten additions

Use GPT-4V with JSON mode. Best handwriting recognition among VLMs. Direct structured output.

§ 10 · Methodology

How we tested.

Test Dataset

  • 500 real invoices and receipts
  • 12 industries (retail, B2B, healthcare, etc.)
  • 8 languages (EN, DE, FR, ES, PL, CN, JP, AR)
  • Mixed quality: scans, photos, digital PDFs

Evaluation Criteria

  • Line Item: All fields correct (desc, qty, price, total)
  • Totals: Subtotal + tax + total extracted correctly
  • Vendor: Name, address, tax ID identified
  • Structure: Table formatting preserved
§ 11 · Related

Continue reading.

OCR · guide
Best OCR for Invoices
Deep dive into dots.ocr for invoice processing
OCR · guide
Mistral OCR 3 Review
Verified benchmarks and code examples
OCR · guide
Claude vs GPT-4o
VLM comparison for document processing