Invoice & Receipt Extraction for Opex Coding
Document AI extracts line items from supplier invoices and auto-codes them to the correct cost category and property, eliminating manual data entry across the portfolio. (e.g., AppFolio, Rossum)
Property processAcquireLeaseOccupyMaintainBillRenewVacateDispose
By Don, DoneThat’s AI coach · updated
Overview
Property accountants spend a large share of the bill cycle typing supplier invoices and receipts into the general ledger: vendor, date, amount, tax, property, and operating-expense (opex) category. The work is repetitive, and it scales with every extra asset. Document AI reads the page (or PDF), pulls line items, and proposes a cost code and property so the accountant is reviewing a draft posting rather than keying from a scan.
This page is for the person who codes opex for a portfolio in a property management or accounting system (for example AppFolio) and who may already use a document-capture product (for example Rossum) for other AP work. Extraction and coding are model outputs. Accounts payable still posts. When the invoice image cannot be read, the model returns empty output rather than a guessed bill.
What extraction and coding replace in the bill cycle
Manual opex coding starts when a landscaper, utility, contractor, or insurance broker sends a PDF, a photo of a till receipt, or a multi-page statement. Someone opens the file, finds the header fields, then walks line by line: which property, which chart-of-accounts leaf, whether the charge is recoverable, and whether tax is included. Across dozens of properties the same vendor appears under slightly different names, and the same kind of spend lands in different GL buckets depending on who last coded it.
Document AI targets that data-entry loop, not the decision to pay. It turns an unstructured invoice into structured fields: supplier identity, invoice number, invoice date, due date, currency, totals, tax lines, and per-line descriptions and amounts. A second step maps each line (or the whole invoice, when the bill is a single charge) to a property identifier and an opex category that already exists in your chart and property list.
The speed gain is in the hours between “bill arrived” and “draft ready for AP.” The control gain is consistency: the same landscaping invoice type should not be Repairs at one asset and Grounds at the next unless a human chose that split.
Related billing work that still needs a human review after the books are coded includes CAM & Service Charge Audit. Extraction here is about getting opex into the right buckets quickly; CAM audit is about whether recoveries later match the lease.
How the model reads invoices and proposes codes
Treat the pipeline as two jobs that can fail independently: read the document, then classify the spend.
Reading covers PDFs from vendors, emailed attachments, and photos of paper receipts. Header extraction is usually more reliable than line-item extraction. A single-total utility bill with a clear account number is a different problem from a contractor invoice with twenty job lines, retainage, and a change order. Receipts add noise: crumpled paper, glare, truncated totals, and missing vendor legal names.
Coding uses whatever master data you already trust. Typical inputs are the property code or address the vendor printed (often wrong or missing), the ship-to or job site, the vendor master (so “ABC Landscaping LLC” and “ABC Landscape” collapse to one payee), and your opex tree (utilities, R&M, contracts, admin, insurance, and so on). Some teams code at invoice level when every line is the same property and category. Others require line-level coding when one invoice covers a campus, a master policy, or mixed recoverable and non-recoverable work.
A practical output for the accountant is a table: extracted field, confidence or “needs review” flag, proposed property, proposed GL or cost category, and the raw line text. Low-confidence rows stay in a queue. High-confidence rows can still be wrong (wrong building on a shared vendor, wrong tax treatment), which is why posting stays with AP.
If you already run a capture tool such as Rossum, keep that as the extraction layer and put coding next to it: do not run two competing OCR stacks on the same file. If capture already lives inside AppFolio or another PMS, use the model only for the fields and codes the native capture does not fill reliably.
Empty output when the image cannot be read
Unreadable files are common in property AP: a dark phone photo, a faxed utility bill, a password-protected PDF, a statement that is actually a scan of a scan, or an image that is not an invoice (a packing slip, a quote, a W-9). The correct model behavior is empty output for that document: no invented invoice number, no placeholder total, no “best guess” property.
Empty output is an operational signal, not a silent skip. Route those files to a human capture step (re-scan, request a new PDF from the vendor, or key from a better original). Do not let an empty extraction auto-advance into “coded and ready to post.” Downstream, AP should see a distinct status such as “unreadable” so the bill is not lost in a completed queue.
If only part of the page is readable (header clear, lines illegible), return empty line items even if headers extracted. Partial headers without lines still leave the accountant coding from the image. It is safer to fail the document than to post a header-only bill that later needs a reversing entry.
Human review, then AP posts
The model extracts and codes. The accountant (or AP clerk) confirms or corrects property and category, checks vendor and tax, and matches to a purchase order or contract when one exists. Only after that confirmation does AP post in the accounting or property system.
Keep the split of duties explicit. Extraction quality is a document problem. Coding quality is a chart-of-accounts and property-master problem. Posting is a control problem: duplicate invoice numbers, unapproved vendors, amounts over approval limits, and period cut-off still belong to AP policy, not to the model.
Review workload should concentrate on exceptions: new vendors, first invoice at a property, mixed-property bills, credits and debit memos, retainage, and any row below a confidence threshold you set. Do not require line-by-line retyping of fields the reviewer already accepted. The review UI should show the source image beside the proposed coding so the human is checking, not re-keying.
When a reviewer changes a code, store the correction. That feedback is how you stop the same landscaping vendor from landing in the wrong bucket every month. Without a feedback loop, the model will keep proposing yesterday’s mistakes.
Portfolio pitfalls that break naive coding
Property portfolios break generic AP extraction in predictable ways.
Vendors bill a legal entity or a region, not the asset the work hit. A national elevator contractor may send one invoice for five buildings. Coding must split by line, by job number, or by a allocation rule you already use, not by stuffing the full amount onto the first property in the vendor master.
Utility and municipal bills often identify the service address in a format that does not match your property name. Maintain a mapping from meter, account number, or service address to property code. Do not rely on fuzzy matching the city line of the bill to the asset name.
CAM-recoverable versus owner opex is a lease question, not an OCR question. Extraction can capture the vendor’s description. It should not mark a line recoverable unless that rule is in your recoverability table and a human (or a later CAM & Service Charge Audit process) can still override it.
Receipts from site staff (hardware store, emergency plumber) often lack a property code. Pair extraction with a simple intake rule: who submitted the receipt, which asset they are assigned to, and a cap that forces review above a set amount. The model still returns empty output if the photo cannot be read.
Duplicates are frequent when the same PDF arrives by email and by portal. Extraction can surface invoice number plus vendor plus amount as a match key; AP still decides whether it is a true duplicate or a reissued original.
What to measure before you widen the rollout
Start with one vendor class and a handful of properties, not the whole ledger. Utilities and repetitive contract invoices (landscaping, janitorial, security) are easier than one-off capex-adjacent contractor bills that sit on the opex/capex boundary.
Measure time from invoice receipt to draft coding, share of documents that return empty output (unreadable), share that require coding changes in review, and posting error rate after go-live (wrong property or wrong category that needed a journal). If unreadable rates are high, fix intake (PDF from the vendor, not photos) before you tune the classifier.
Is this worth automating for you?
Whether this pays back depends on how much time it takes your team today. Most teams estimate that from memory, and the estimate is usually wrong in one direction or the other.
DoneThat reconstructs where the time actually went, with no timers to forget, so you can measure the baseline before committing to a project and check the gain afterward.
Measure the baseline first