Automation · Finance
How to build AP invoice processing
Invoices arrive as PDFs in a shared mailbox and somebody retypes them into the ledger. Here is the model behind processing that does not need retyping, the prompts that build it, and what it takes to run in production.
Built with Tray Headless
- System Gmail
- Step Extract with scores
- Step Human check below threshold
- Step Match to the PO
- System NetSuite
Extraction produces a confidence score per field, and anything below the threshold stops at a person before it can reach the ledger.
The short answer
What is AP invoice processing?
AP invoice processing has four moving parts: intake from wherever invoices actually arrive instead of one channel you mandated, extraction with a confidence score and a human check on anything uncertain, duplicate detection before anything is posted, and matching against the purchase order with a clear exception path. The mistake that costs most is trusting extraction. A model reading a PDF is right most of the time, and posting the times it is wrong straight to the ledger is how a supplier gets paid a decimal place too much.
What matters here
- Take invoices from where they already arrive. Mandating a portal means half of them still come by email and nobody watches that inbox.
- Score the extraction and check the uncertain ones. A confident wrong number posted to the ledger is worse than a slow one.
- Detect duplicates before posting, on supplier plus invoice number plus amount. The same invoice arrives twice more often than anybody expects.
- Never post an unmatched invoice to clear payment. Hold it, name an owner and show the discrepancy.
- Track early payment discounts by deadline. They are free money and they expire in a queue.
Who this is for
You run accounts payable or finance systems. Invoices arrive by email, portal and post, somebody keys them in, and the month end backlog is a known quantity everybody plans around.
How it works in practice
What has to happen between an invoice arriving and a supplier being paid.
- 1
Invoices are taken from every channel they arrive on
A shared mailbox, a supplier portal, and a folder somebody drops scans into. Not one mandated route.
- 2
Extraction produces values with confidence scores
Supplier, invoice number, date, line items, tax and total, each scored instead of asserted.
- 3
Anything uncertain goes to a person before posting
High confidence posts, the middle band is checked, and low confidence is keyed by hand with the image alongside.
- 4
Duplicates are caught before anything reaches the ledger
Supplier plus invoice number, then a fuzzy pass on amount and date for the ones that were re-sent slightly differently.
- 5
The invoice is matched against its purchase order
Within tolerance clears, outside it stops with the discrepancy shown.
- 6
Payment is scheduled against terms and discounts
Early payment discounts surfaced before the deadline, not reported after it.
What AP processing is made of
Four parts, and the second is the difference between automation and a liability.
Multi-channel intake
Mailbox, portal and folder, normalised into one queue. Suppliers send how they send, and a mandated channel captures only the compliant half.
Scored extraction
Every field with a confidence, and a threshold that sends the uncertain ones to a person with the original image beside the form.
Duplicate detection
Before posting, not after. Exact on supplier and invoice number, then fuzzy on amount and date for the re-sends.
Matching with exceptions
Against the purchase order and receipt, with tolerances, and every mismatch assigned to a person instead of pooled.
The Tray Headless prompts
Paste these into Claude Code or Codex with the Tray Headless plugin installed. Each stage runs on its own. The systems named in them are the worked example rather than a requirement, and every prompt says so.
Once per project, run
/tray-workflows:set-workspace
to pick the workspace these build in. Point it at a sandbox first.
- 1
Start here: take invoices from every channel
Because a mandated portal captures the compliant suppliers only.
Headless skills
build-workflowUse build-workflow. The systems in play are Gmail, NetSuite, Coupa, Google Drive, Slack and Snowflake, or whatever we run in those seats. Before you plan anything, tell me which of them are already authenticated in the workspace, because I do not want a connector stubbed that I have not authenticated. Build intake from all of these into one queue, landing each as a NetSuite VendorBill draft matched against its PurchaseOrder and ItemReceipt: The shared AP mailbox, attachments only, ignoring the reply chains The supplier portal, where suppliers who use it upload A watched folder for scans and anything forwarded on Normalise them into one record with the source, the original file, and the arrival timestamp. Keep the original file forever. It is the evidence and it will be asked for.
- 2
Extract with confidence, and check the uncertain ones
The step where trusting a model too far becomes an overpayment.
Headless skills
build-workflowUse build-workflow. Extract supplier, invoice number, invoice date, due date, currency, line items, tax and total, and give each field a confidence. Then band the result: every field above the high threshold post straight through anything in the middle band queue for a quick human check anything low, or a total that does not equal the sum of lines plus tax key it by hand Always show the original image beside the extracted values in the review screen. A reviewer checking numbers against a form they cannot see is not checking anything. Never post a field the model was unsure about. A confident wrong total becomes a payment.The arithmetic check is the cheapest control here. If lines plus tax does not equal the total, extraction has misread something regardless of how confident it was.
- 3
Catch duplicates before anything posts
The same invoice arrives twice more often than anybody expects.
Before posting, check for duplicates in this order: Exact: same supplier and same invoice number, ever Near: same supplier, same amount, within a few days, different number Fuzzy: same amount and date across two supplier records that may themselves be duplicates in the vendor master Block the exact ones outright. Flag the near ones for review with both invoices shown side by side. Suppliers re-send. A chased invoice arrives again with a new reference, and a statement re-sends everything outstanding. Both of those look like new invoices to anything checking only the number.
- 4
Match, and route what does not
So the only invoices anybody touches are the ones that need touching.
Headless skills
tray-gotchasUse tray-gotchas, then match against the purchase order and receipt with tolerances I can set. Within tolerance clears for payment. Outside it stops and routes to a named person with the order, the receipt and the invoice side by side and the difference highlighted. Handle these: No purchase order at all. Route to the cost centre owner to confirm and attach one, do not reject and do not pay. Partial delivery. Pay for what arrived, keep the balance open. Credit note. Match it to the original invoice rather than treating it as a negative invoice floating on its own. Supplier not in the vendor master. Stop. A new supplier is an onboarding process, not an invoice field.
- 5
Schedule payment against terms, and chase the discounts
Early payment discounts are free money that expires in a queue.
Schedule payment from the supplier terms rather than the invoice date, and surface early payment discounts before their deadline, not after. Report weekly: invoices processed by channel, straight-through rate, average days to process, exceptions by reason, duplicates caught, and discounts available against discounts taken. That last pair is the number that pays for this. A discount missed because an invoice sat in a queue is a cost with nobody attached to it.
- 6
Validate, then hand the thresholds to AP
Because tolerances and confidence bands are finance judgement.
Run the per-step schema checks and the whole-workflow audit before this touches production. Run in review-everything mode for a fortnight first, so the confidence thresholds are set from real invoices, not guessed. Then open the same workflow in Tray Build so accounts payable can move the confidence bands and the matching tolerances in the visual canvas.
What it connects to
Invoices arrive in several places and end up in one ledger.
Gmail
Take invoices from the shared AP mailbox, attachments only, and keep the original message as evidence.
Reads
NetSuite
Read purchase orders, receipts and the vendor master. Post the invoice and clear it for payment.
Reads and writes
Google Drive
Store the original document against the posted invoice, because the ledger entry is not the evidence.
Reads and writes
Slack
Route an exception to the named owner with the discrepancy, and warn before a discount deadline.
Writes
Snowflake
Land processing history, so straight-through rate and discount capture are measurable by supplier.
Writes
Same build, other stacks
The design does not change if you run something else in one of these seats. The same prompts build it against SAP S/4HANA, Google BigQuery, Microsoft Teams, SharePoint, Microsoft Outlook or Oracle.
Named systems are the ones most teams run, not the only ones that work. Each is an authentication in your Tray workspace, referenced by name, so the workflow never holds a credential. Where we have a connector page, the name links to it.
Running it in production
This posts to the ledger and schedules payments. Both are audited and both are irreversible in practice.
It runs where production runs, not on a laptop
Intake from three channels, extraction and matching run continuously on the same engine, including through the month end spike.
The original document is kept, always
Posted values are traceable back to the image they came from, with the extraction confidence recorded. That pairing is what an audit needs.
Credentials are managed, never in code
A credential that can clear an invoice for payment is among the most sensitive you hold. It lives in your workspace, scoped and separately rotatable.
AP owns the thresholds
Confidence bands and matching tolerances open in Tray Build, tuned by the team reviewing the exceptions.
Nothing uncertain posts silently
Below the threshold it waits for a person. A wrong number posted confidently becomes a payment, and recovering an overpayment is a supplier conversation.
Questions people ask
Should extraction post straight to the ledger?
Only above a high confidence threshold, and only when the arithmetic checks out. A confidently wrong total becomes a payment, and recovering an overpayment is a conversation with a supplier.
Why take invoices from multiple channels?
Because mandating a portal captures the suppliers who comply and leaves the rest arriving by email into an inbox nobody watches. Take them where they already come.
How do duplicates get through?
Suppliers re-send. A chased invoice returns with a new reference and a statement re-sends everything outstanding, so checking the invoice number alone misses both. Match on supplier, amount and date as well.
What happens to an invoice with no purchase order?
It stops and routes to the cost centre owner to confirm and attach one. Rejecting it annoys a supplier who did nothing wrong, and paying it defeats the control.
What is the number that justifies this?
Early payment discounts available against discounts taken. They are free money, they expire in a queue, and almost nobody measures the gap.
Vibe-coding app guides
Vibe-code an entire app with Helix
This moves the data between systems. It does not give anybody a screen to work in. Build that app in Claude Code, Codex or Cursor, then deploy and run it governed on Tray Helix. Same kind of guide, same kind of prompts.
How to build an invoice approval queue (opens helix.tray.ai in a new tab)
Related guides
Finance
How to build a procure-to-pay integration
Requisition to PO to receipt to payment, with the approval matrix as data, three-way matching, and the budget checked before the commitment. The prompts.
Finance
How to build collections and dunning
Escalate on the customer rather than the invoice, stop the moment they pay or dispute, and never dun an account somebody is negotiating with. The prompts.
Finance
How to build an expense and card feed sync
Match card transactions to receipts, code from the merchant instead of the claimant, and chase the missing ones before month end. The prompts that build it.
Finance
How to build a vendor master sync
Onboard a supplier once, verify bank details out of band, keep one record per legal entity, and make a change to payment details an event. The prompts.
AI operations
How to build a document intelligence pipeline
Score confidence per field rather than per document, validate against a system of record, and route only the uncertain fields to a person. The prompts.
Last reviewed September 2026.