Code and dense tables are folded away. Open any of them on demand.
Live demo · no signup
Try this use case
Edit the text if you like, then press run. Laya answers every question at once, with a probability for each option.
The questions it answers
matches_orderyes / noDo the quantities and unit prices on `invoice` match `purchase_order` and `goods_receipt`?duplicateyes / noIs `invoice` a duplicate of one in `recent_invoices_same_vendor`?discrepancy_severityscoreHow severe is any discrepancy between `invoice` and `purchase_order`?dispositionchoiceWhat should accounts payable do with `invoice`?
The answers appear here as bars: the longer the bar, the more likely Laya thinks that option is.
Show the full API requestHide technical details· JSON
What is automated invoice processing?
Automated invoice processing means software reads each supplier invoice and decides what happens next without a clerk handling every one. Laya covers the decision step after extraction: does the invoice match the purchase order, is it a duplicate, how serious is any discrepancy, and should it be approved, held or rejected, each with a probability.
OCR and document AI now pull invoice numbers, line items and totals out of PDFs reliably. What remains manual is the decision layer. For each invoice, an accounts-payable clerk compares it with the purchase order and goods receipt (the three-way match), checks whether the vendor has already billed it, judges whether a price difference is within tolerance, and chooses what happens next: pay, hold, ask for a credit note or reject.
Rules engines handle the clean cases: exact match, pay. They struggle with the rest, because the rest is fuzzy: a unit price 7% above the PO, a line with a slightly different SKU description, an invoice number that differs by one character from last month's. Those exceptions are where clerks spend their time, and where overpayments and duplicate payments slip through.
This decision layer has a fixed shape (the same five questions for every invoice), structured input (JSON from your extraction step and ERP), and asymmetric error costs (paying a duplicate is far worse than holding a good invoice for a day). It is a strong fit for a calibrated decision model with explicit escalation.
Why a fine-tuned decision model rather than an LLM
Laya ships a checkpoint built for this workflow. laya-typed-decisions is ModernBERT-large (421M parameters, 1,024-token context) fine-tuned on four synthetic typed-decision workflows, one of which is invoice_processing. On the model card's typed-decisions benchmark (400 cases, 2,000 decisions), it reaches 0.766 accuracy overall and 0.804 on invoice processing, above a 0.735 teacher self-agreement ceiling and above the published 0.727 for TypeSafe Jev 1.13.0. Its Brier score is 0.062 against Jev's published 0.148.
The context matters: the same benchmark puts the base English checkpoint at 0.362, below the 0.461 per-question majority baseline. The capability comes from fine-tuning. That is the right mental model for invoice decisions generally: a small model specialised on your decision is faster and better calibrated than a general model prompted for it.
Other reasons to prefer a decision model here:
- No generated text. Answers are one of your labels or a probability. Nothing to parse, no invented invoice numbers or explanations. The answer can still be wrong, which is what the probabilities and thresholds are for.
- Calibrated probabilities let you set tolerance for automation in terms of expected error, rather than trusting a free-text "looks fine".
- Latency and cost. Five questions are answered in one forward pass (the model card reports 84.5 ms for five questions on a T4 for the English checkpoint, which uses the same ModernBERT-large encoder; it publishes no separate latency figure for typed-decisions, and network time is extra), billed as 5 credits. See pricing.
Designing invoice questions for the typed-decisions checkpoint
The router recognises the invoice-processing workflow by its exact set of question ids: discrepancy_severity, disposition, duplicate, matches_order and urgency. Use those ids and no others if you want to match the fine-tuned workflow. Adding a sixth question, or renaming one, means the set no longer matches.
Even with matching ids, the hosted router does not switch checkpoints silently. Pass "model": "typed-decisions" in the request body. (The self-hosted Router also supports opt-in auto task detection on the id set, which is off by default.)
Be clear about what is and is not published. The model card and package publish the workflow names and question ids, not the exact instructions and criteria text used in the synthetic training data. The criteria in the example on this page are illustrative, written for a typical three-way-match process. The fine-tuned checkpoint learned from specific synthetic phrasing and synthetic invoices, so your wording and your data will differ. Validate on a labelled sample of your own invoices before automating anything.
Question-by-question:
matches_order(noul): the three-way-match check. Put the invoice, PO and goods receipt in the state as structured JSON so the comparison is visible.duplicate(noul): include the vendor's recent invoices (number, date, total) in the state. The model can only compare what it can see. Keep exact-duplicate checks (same number, same total) in your ERP; use Laya for near-duplicates.discrepancy_severity(score): four ordinal levels, each defined by evidence. Put your tolerance rule in the level text if you have one.disposition(choice): the action. Keep an explicit human option (hold_for_review).urgency(score): include due date and discount terms in the state.
Mind the token budget: the checkpoint reads 1,024 tokens per question, about 768 of them for state. Send only the relevant lines, not the full vendor master.
Thresholds and escalation for accounts payable
In accounts payable, the question is not "what is the answer" but "when is it safe not to look". Build the policy around confidence and a conservative default.
Use confidence, not act_probability. The model card and issue #185 report that action.act_probability reads close to 1.0 for almost every input and that its raw logits run against correctness (AUROC 0.30 on 396 labelled decisions), while confidence reached 0.77 on the same items. Log act_probability so you can add it as a second condition once a checkpoint fixes it.
Refit calibration on your data. The typed-decisions checkpoint's ECE on its own benchmark is 0.213, which is higher than its Brier score suggests; the model card reports that refitting one temperature per (question type, option count) cuts ECE sharply on the base checkpoints (0.466 to 0.081 for English). On your invoices, fit temperatures on a few hundred labelled decisions and pick thresholds from the resulting reliability diagram.
A starting policy, deliberately asymmetric:
| Condition | Action |
|---|---|
duplicate.noul ≥ 0.3 | Hold; never auto-pay a possible duplicate |
disposition = approve, confidence ≥ 0.8, matches_order.noul ≥ 0.9, discrepancy_severity.score < 0.5 | Auto-approve |
disposition = request_credit_note, confidence ≥ 0.7 | Draft credit-note request for a clerk to send |
| Anything else | Hold for review, prioritised by urgency.score |
Show technical detailsHide technical details· python sample
Note the noul thresholds use the raw probability (noul), not confidence, because the direction matters. Track the auto-approve rate and audit a random sample of auto-approved invoices every week. See act/escalate routing.
Integration: sending extracted invoices to /v1/systemone
Call the endpoint after your extraction step and ERP lookup, with model set to typed-decisions.
Show technical detailsHide technical details· bash sample
Show technical detailsHide technical details· python sample
Show technical detailsHide technical details· typescript sample
Store the request and full response with the invoice record. Auditors will ask why an invoice was auto-approved, and the stored probabilities are the answer. Sign up for a key or read the docs.
Data stays in Switzerland: supplier invoices are not stored
Invoices carry supplier bank details, prices and contract terms. Laya Studio's primary inference pool runs on dedicated GPUs located in Switzerland, and every API response says where it was processed in the x-laya-region header. The text and questions you send are processed in memory and discarded when the answer is returned: they are never written to a database or log, and never used to train anything.
Turn on Swiss-only mode for a workspace (or send the x-laya-residency: ch header on a request) and requests are only ever answered in Switzerland. If the Swiss pool is unavailable you get an error, never a silent detour abroad. For billing and debugging, only request metadata (time, status, number of questions, latency) is kept, for 30 days. You remain responsible for your legal basis to process personal data. Details: Swiss data residency.
Limitations of automated invoice decisions
- Synthetic training data. The typed-decisions checkpoint was fine-tuned on synthetic workflows. The 0.804 invoice-processing figure is on that benchmark's test split, not on real invoices. Your accuracy will differ; measure it.
- The criteria text is yours. The model card does not publish the exact criteria used in training. Wording that differs from the training data may reduce accuracy; test variations.
- It does not do arithmetic reliably. An encoder classifier reads numbers as tokens. Compute totals, tolerances and exact duplicate matches in code and put the results in the state (for example
"price_diff_pct": 6.9), rather than asking the model to calculate. - Context is limited to about 768 tokens of state. Invoices with hundreds of lines need summarising first.
- Score questions are the weakest primitive (0.723 accuracy by primitive on typed-decisions, against 0.857 for noul). Treat
discrepancy_severityas a triage signal. - Not an approval authority. Keep segregation of duties and payment controls in place; Laya informs the decision, your controls enforce it.
Frequently asked questions
How can I detect duplicate invoices automatically?
Are invoices stored when processed by Laya Studio?
Which question ids select the invoice-processing workflow?
How accurate is Laya on invoice processing?
Can Laya extract fields from invoice PDFs?
Should I let Laya auto-approve invoices?
Can I add my own questions to the invoice workflow?
Sources
Last updated . Laya Studio is an independent hosted service for the open-source Laya model (Apache-2.0, © Convai Innovations) and is not affiliated with Convai Innovations or TypeSafe.