Rishabh's comment covers the arithmetic side, so I'll add two schema issues. First, your Swiss receipt test exposes a gap: totalAmount is a bare Number with no currency field, so CHF 45.50 and EUR 45.50 come out identical. For a B2B pipeline that feeds accounting, an ISO 4217 currency field is close to mandatory. Second, dueDate as a plain String has two problems. Receipts like the hotel one usually have no due date at all, and in strict structured outputs every property must be present. Unless the type allows null, the model is pushed to fill something in. And without a format rule, a date like 03.04.2026 can be read as March or April depending on the reader's country. Asking for YYYY-MM-DD or null, plus a separate invoiceDate field, makes the output safe to sort and compare. One more thing worth checking: as far as I know, the image_url input on the chat endpoint takes images, not PDFs, so PDF uploads probably need the file input or a conversion step first.