Start with text you can inspect
Pass an invoice's already-extracted text to a chat model and request a small record. This recipe does not read PDFs, perform OCR, find character coordinates, or assign confidence scores. If the original document is an image, text extraction is a separate step that your application must provide and check.
Use the output to assist review. A model's record is not authorization to pay an invoice. Keep the source text available so a person can resolve missing fields, ambiguous taxes, and currency symbols.
Validate the returned record
Ask for JSON with invoice number, currency, subtotal, tax, and total. Request monetary amounts as decimal strings, then validate structure and arithmetic in Python. This complete local example parses a simulated model response; it makes no API request.
from decimal import Decimal, InvalidOperation
import json
import re
FIELDS = {"invoice_number", "currency", "subtotal", "tax", "total"}
def parse_invoice(text):
value = json.loads(text)
if not isinstance(value, dict) or set(value) != FIELDS:
raise ValueError("Unexpected invoice fields")
if not all(isinstance(value[k], str) for k in FIELDS):
raise ValueError("All fields must be strings")
if not value["invoice_number"].strip():
raise ValueError("Missing invoice number")
if not re.fullmatch(r"[A-Z]{3}", value["currency"]):
raise ValueError("Use an explicit three-letter currency")
try:
amounts = [Decimal(value[k]) for k in ("subtotal", "tax", "total")]
except InvalidOperation as error:
raise ValueError("Invalid decimal amount") from error
if any(not amount.is_finite() or amount < 0 for amount in amounts):
raise ValueError("Expected finite non-negative amounts")
subtotal, tax, total = amounts
if subtotal + tax != total:
raise ValueError("Totals require review")
return value
sample = '{"invoice_number":"DEMO-1","currency":"USD",' \
'"subtotal":"100.00","tax":"16.00","total":"116.00"}'
print(parse_invoice(sample))Add the model request
Call https://api.mandapi.com/v1 through the OpenAI-compatible client using MANDAPI_API_KEY and MANDAPI_MODEL_ID. Ask the model to treat invoice text as data and return only the specified fields. Use null or a separate review result for missing information; do not fabricate amounts. This parser intentionally rejects incomplete records.
Check the result
Try wrong totals, ambiguous currency, missing values, and non-numeric amounts. Adjust the schema for discounts, withholding, or tax-inclusive invoices before using such documents. A matching sum checks consistency only; it does not prove that the invoice is genuine or correctly extracted.