Use case · Invoices

Invoice OCR API

Invoice OCR with Mahad OCR reads an invoice (PDF or photo) and returns the supplier, invoice number, dates, currency, subtotal, tax, total and line items as JSON. The totals are checked by arithmetic — subtotal plus tax must equal the total — and an invoice that looks like one your organisation already uploaded is flagged as a suspected duplicate.

Fields returned

KeyWhat it holds
vendorSupplier (required)
invoice_number, invoice_dateRequired
total_amountRequired
buyer, due_date, currency, po_numberWhere printed
subtotal, tax_amountWhere printed — used for the arithmetic check
line_items[]Each line as printed

vendor, invoice_number, invoice_date and total_amount are required; a missing one is listed in missing_required.

How ✓ and ⚠ work here

  • ✓ “The totals add up (subtotal + tax = total)” — subtotal, tax and total are marked arithmetic when they agree within 0.05.
  • ⚠ Other invoice fields are read by one reader and marked “Read by one reader only — please check it”.
  • ⚠ DUPLICATE_SUSPECTED: the same file, the same supplier + invoice number, or the same supplier + amount + date as an earlier invoice of your organisation sends it to review.
  • ⚠ ARITHMETIC_MISMATCH: amounts that do not add up send it to review.

Example request and response

Fictional data, real response shape (trimmed to the keys that matter here). Full field list in the API reference.

curl -X POST https://api.mahadocr.com/v1/documents/upload \
  -H "X-MahadDoc-API-Key: mk_live_YOUR_KEY" \
  -F "[email protected]" \
  -F "doc_type=invoice" \
  -F "outputs=xlsx"
{
  "id": "DOC_3f9a1c7e2b40",
  "status": "verified",
  "result": {
    "document_type": "invoice",
    "values": {
      "vendor": "Test Supplies Trading", "invoice_number": "INV-2026-0142",
      "invoice_date": "2026-09-14", "currency": "QAR",
      "subtotal": "1000.00", "tax_amount": "50.00", "total_amount": "1050.00"
    },
    "field_evidence": { "vendor": "model", "invoice_number": "model",
                        "subtotal": "arithmetic", "tax_amount": "arithmetic", "total_amount": "arithmetic" },
    "outputs": { "json": "/v1/documents/DOC_3f9a1c7e2b40",
                 "xlsx": "/v1/documents/DOC_3f9a1c7e2b40/outputs/xlsx" }
  }
}

Limits

  • Invoices are read by one reader. Only the totals get an independent check (arithmetic); supplier, number and dates are ⚠ for a person to confirm.
  • Mahad OCR does not validate tax registration numbers, e-invoicing signatures or QR codes against any tax authority.
  • A PDF is read up to its first 5 pages; longer invoices go to review with “pages not processed”.
  • Excel output (outputs=xlsx) contains the fields and line items; there is no direct ERP connector.

How to do it

  1. 1POST the invoice to /v1/documents/upload with doc_type=invoice (optional) and outputs=xlsx if you want a spreadsheet.
  2. 2Poll GET /v1/documents/{id} until result.status is not processing.
  3. 3Check result.field_evidence: “arithmetic” totals are confirmed; “model” fields need a glance.
  4. 4Download GET /v1/documents/{id}/outputs/xlsx or map result.values into your system.

Frequently asked questions

Does Mahad OCR check invoice totals?

Yes. When subtotal and total are both read, subtotal + tax must equal total (within 0.05). If they agree, all three are marked ✓ arithmetic; if not, the invoice goes to review.

How are duplicate invoices detected?

Within your organisation: the same file, the same supplier and invoice number, or the same supplier, amount and date as an earlier invoice. It finishes as DUPLICATE_SUSPECTED and goes to review.

Are line items extracted?

Yes, as printed, in line_items. They are included in the Excel output.

Can I export invoices to Excel?

Add outputs=xlsx to the upload, then download GET /v1/documents/{id}/outputs/xlsx once reading has finished.

Is the supplier’s VAT number verified?

No. Tax numbers are read as printed; there is no tax-authority lookup.

Does it handle Arabic invoices?

Arabic text is read in the script printed. A bilingual label such as “Total / الإجمالي” publishes its Latin part as the value label.

Related